思路:当a,b的根节点find(a)与find(b)不同时,就直接将这两个数连接起来。由于每个树的根节点的kind值一定为0,所以,对于a,b的kind值相同,我们就讲其中一个根的kind值变为1,当下次再遍历该节点的时候,a与b的kind值就会变得不同。如果a,b的kind值相同,那么就不用变。
看代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define Maxn 20010 using namespace std; int set[Maxn],kind[Maxn]; int find(int x) { if(x!=set[x]) { int temp=set[x]; set[x]=find(set[x]); kind[x]=(kind[x]+kind[temp])%2;//保证子节点与父节点的不同。
} return set[x]; } int merg(int a,int b) { int x,y; x=find(a); y=find(b); if(x==y) { if(kind[a]==kind[b]) return 0; return 1; } set[x]=y; kind[x]=(kind[a]-kind[b]+1)%2; return 1; } int main() { int n,m,i,j,a,b,t,Case=0,flag=0; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=0;i<=n;i++) set[i]=i; flag=0; memset(kind,0,sizeof(kind)); for(i=1;i<=m;i++) { scanf("%d%d",&a,&b); if(!merg(a,b)) { flag=1; break; } } for(i++;i<=m;i++) scanf("%d%d",&a,&b); if(flag) printf("Scenario #%d: Suspicious bugs found! ",++Case); else printf("Scenario #%d: No suspicious bugs found! ",++Case); } return 0; }