hdu1829
http://acm.hdu.edu.cn/showproblem.php?pid=1829
跟“find them,catch them”思路一样
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h>//其实只有一个集合,只是在每条边上赋了值罢了,权值 #include<string.h> int bin[100002],zt[100002]; int findx(int x) { int r=bin[x]; if(x==bin[x]) return bin[x]; bin[x]=findx(bin[x]);//递归方法查找根结点 zt[x]=(zt[x]==zt[r])?0:1;//成立时表示子节点根父亲结点同类,前提是在同一集合里比较 return bin[x]; } void uni(int x,int y,int bx,int by) { bin[bx]=by;//将两个集合合并 zt[bx]=(zt[x]==zt[y])?1:0;//因为本来就是分开的两个集合,所以里面的元素比较时就应反向比较 } int main() { int n,m,i,x,y,flag,t,a,b,ca=1; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=1;i<=n;i++) bin[i] = i,zt[i]=0;//初始化 flag=0; while(m--) { scanf("%d %d",&x,&y); a=findx(x); b=findx(y); if(a!=b)uni(x,y,a,b);//没有相同根结点,表示是两个不同的集合,所以应该合并,并对zt值做修改 else if(a==b)//在同一个集合里就可以判断 if(zt[x]==zt[y])//相同就是同类 flag=1; } if(flag) printf("Scenario #%d:\nSuspicious bugs found!\n\n",ca++); else printf("Scenario #%d:\nNo suspicious bugs found!\n\n",ca++); } return 0; }