• codeforces 652 E Pursuit For Artifacts


    传送门

    转载请注明出处:

    http://www.cnblogs.com/hzoi-wangxh/p/7738614.html

    题解:
    求原图的边双。
    缩点重建图时,如果z[i]为1且两个端点在一个连通块内,连通块的值设为1,如果不在,边权为1.
    缩点之后我们得到的是一棵树,所以只需要从起点向终点跑一个dfs,最后检验终点权值是否为0。

    附上代码:

    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define mmin(a,b) (a<b?a:b)
    #define mmax(a,b) (a>b?a:b)
    struct tree{
        int u,v,next,d;
    }l[601000];
    struct tree2{
        int u,v,next,d;
    }l2[601000];
    int n,m,lian[301000],e,d[301000],cnt,dis[301000];
    int fa[301000],dfn[301000],low[301000],num;
    int st[301000],head,be,en;
    bool pd[301000];
    void bian(int,int,int);
    void tar(int,int);
    void bian2(int,int,int);
    void dfs(int,int);
    int main()
    {
    //  freopen("in.txt","r",stdin);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            bian(x,y,z);
            bian(y,x,z);
        }
        for(int i=1;i<=n;i++)
            if(dfn[i]==0)
                tar(i,0);
        memset(lian,0,sizeof(lian));
        int cc=e;
        e=0;
        for(int i=1;i<=cc;i++)
        {
            int u=fa[l[i].u],v=fa[l[i].v];
            if(u==v)
                d[u]=mmax(l[i].d,d[u]);
            else
                bian2(u,v,l[i].d);
        }
        scanf("%d%d",&be,&en);
        dis[fa[be]]=d[fa[be]];
        dfs(fa[be],fa[be]);
        if(dis[fa[en]]==0) printf("NO");
        else printf("YES");
    //  while(1);
        return 0;
    }
    void bian(int x,int y,int z)
    {
        e++;
        l[e].u=x;
        l[e].v=y;
        l[e].d=z;
        l[e].next=lian[x];
        lian[x]=e;
    }
    void tar(int x,int y)
    {
        dfn[x]=low[x]=++num;
        st[++head]=x;
        pd[x]=1;
        for(int i=lian[x];i;i=l[i].next)
        {
            int v=l[i].v;
            if(v==y) continue;
            if(dfn[v]==0)
            {
                tar(v,x);
                low[x]=mmin(low[x],low[v]);
            }
            else
                if(pd[v]==1)
                    low[x]=mmin(dfn[v],low[x]);
        }
        if(dfn[x]==low[x])
        {
            int temp;
            cnt++;
            while(1)
            {
                temp=st[head];head--;
                pd[temp]=0;
                fa[temp]=cnt;
                if(temp==x) break;
            }
        }
    }
    void bian2(int x,int y,int z)
    {
        e++;
        l2[e].u=x;
        l2[e].v=y;
        l2[e].d=z;
        l2[e].next=lian[x];
        lian[x]=e;
    }
    void dfs(int x,int y)
    {
        for(int i=lian[x];i;i=l2[i].next)
        {
            int v=l2[i].v;
            if(v==y) continue;
            dis[v]=dis[x]+d[v]+l2[i].d;
            dfs(v,x);
        }
    }
  • 相关阅读:
    初学Java——数组
    Ubuntu下将软件添加到快捷启动栏的问题
    初学Java——方法
    初学Java——选择
    初学Java——常用类之Math笔记
    初学Java——基本程序设计笔记(2)
    初学Java——基本程序设计笔记(1)
    关于IE浏览器里修改元素style属性的问题
    2.22,2.24工作进度
    2.21工作进度
  • 原文地址:https://www.cnblogs.com/hzoi-wangxh/p/7738614.html
Copyright © 2020-2023  润新知