hdu3478(图的联通+二分图判断)

来源:互联网 发布:linux who命令 编辑:程序博客网 时间:2024/05/17 03:48

链接:点击打开链接

题意:判断某一时刻可不可能走到任意一个点

代码:

#include <queue>#include <vector>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;int par[200005],ran[200005],x[500005],y[500005];void init(int n){    int i;    for(i=0;i<=n+2;i++)    par[i]=i;}int found(int x){    if(par[x]!=x)    par[x]=found(par[x]);    return par[x];}void unite(int x,int y){    x=found(x);    y=found(y);    if(x==y)    return;    if(ran[x]<ran[y])    par[x]=y;    else{    par[y]=x;    if(ran[x]==ran[y])    ran[x]++;    }}bool same(int x,int y){    return found(x)==found(y);}int judge1(int n,int m){    int i,sum;    sum=0;    init(n);    for(i=0;i<m;i++)    unite(x[i],y[i]);    for(i=0;i<n;i++)    if(par[i]==i)    sum++;    if(sum==1)    return 1;    return 0;}                                               //并查集判断图是否联通int judge2(int n,int m){    int i;    init(2*n);    unite(x[0],y[0]+n);    unite(y[0],x[0]+n);    for(i=1;i<m;i++){        if(same(x[i],y[i])||same(x[i]+n,y[i]+n))        return 0;        unite(x[i],y[i]+n);        unite(y[i],x[i]+n);    }    return 1;}                                               //并查集判断是否是二分图int main(){                                     //因为二分图永远无法走到自己一边的点,因此    int t,n,m,st,i,j,k,cas;                     //问题就变为判断是否是二分图    scanf("%d",&t);    for(cas=1;cas<=t;cas++){        scanf("%d%d%d",&n,&m,&st);        for(i=0;i<m;i++)        scanf("%d%d",&x[i],&y[i]);        if(!judge1(n,m)){            printf("Case %d: NO\n",cas);            continue;        }        if(judge2(n,m)  )        printf("Case %d: NO\n",cas);        else        printf("Case %d: YES\n",cas);    }    return 0;}

0 0
原创粉丝点击