codeforces 652 E Pursuit For Artifacts

来源:互联网 发布:淘宝店没生意怎么推广 编辑:程序博客网 时间:2024/05/22 09:50

传送门

题解:
求原图的边双。
缩点重建图时,如果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);    }}
阅读全文
0 0