链接:点击打开链接
题意:判断某一时刻可不可能走到任意一个点
代码:
#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;
}