最基础的并查集,是1182的简化版,这个只有两种关系,同类or异类,我们用个rank[]数组表示他们之间的关系,0:同类,1:异类。
a-->b的关系满足传递性:a-->x-->y-->b;
#include<stdio.h>
#include<algorithm>
struct{
int pre;
int rank;
}bug[2002];
int n,pairs;
void makeset(int t)
{
bug[t].pre=-1;
bug[t].rank=0;
}
int find(int i)//寻找i节点所在树的根节点
{
int t=bug[i].pre;
if(t<0)
return i;
bug[i].pre=find(t);//路径压缩,修改rank[]的值
bug[i].rank=(bug[i].rank+bug[t].rank)%2;
return bug[i].pre;
}
int main()
{
int time,tt;
scanf("%d",&time);
for(tt=1;tt<=time;tt++)
{
int n,pair,a,b,x,y,i;
memset(bug,0,sizeof(bug));
scanf("%d%d",&n,&pair);
for(i=1;i<=n;i++)
makeset(i);
int flag=0;
for(i=0;i<pair;i++)
{
scanf("%d%d",&x,&y);
if(flag)
continue;
a=find(x);
b=find(y);
if(a==b)
{
if(bug[x].rank==bug[y].rank)//如果x,y已经在一个集合,且他们与根节点的关系相同
flag=1;
}
else//不在一个集合
{
bug[a].pre=b;
bug[a].rank=(bug[x].rank+bug[y].rank+1)%2;
//bug[a].rank=bug[x].rank(a-->x)+bug[y].rank(x-->y)+bug[b].rank(y-->b);
}
}
printf("Scenario #%d:/n",tt);
if(flag)
printf("Suspicious bugs found!/n/n");
else
printf("No suspicious bugs found!/n/n");
}
return 0;
}