题目链接:http://poj.org/problem?id=2492
用 0 1表示两种性别
用sum[i]表示节点i到根节点的距离,f[i]记录i的根节点。
f[rb]=ra;
带权路径压缩:sum[rb]=(sum[a]-sum[b]+1)%2;
#include<iostream> #include<cstdio> #include<cstring> #include<math.h> #include<algorithm> using namespace std; const int INF=0x3f3f3f3f; const int maxn=2005; int T,n,m; int f[maxn],sum[maxn]; void Make_Set(){ for(int i=1;i<=n;i++) f[i]=i,sum[i]=0; } int find(int x){ if(f[x]!=x){ int tmp=f[x]; f[x]=find(f[x]); sum[x]=(sum[tmp]+sum[x])%2; } return f[x]; } bool Union(int a,int b){ int ra=find(a); int rb=find(b); if(ra==rb&&sum[a]==sum[b]) return false; f[ra]=rb; sum[ra]=(sum[b]-sum[a]+1)%2; return true; } int main() { #ifndef ONLINE_JUDGE freopen("test.in","r",stdin); freopen("test.out","w",stdout); #endif int cas=1; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); Make_Set(); bool flag=true; int a,b; while(m--){ scanf("%d%d",&a,&b); if(!flag) continue; if(!Union(a,b)) flag=false; } printf("Scenario #%d:\n",cas++); if(!flag) printf("Suspicious bugs found!\n"); else printf("No suspicious bugs found!\n"); putchar(10); } return 0; }