并查集题目,并的意思就是将两个不同类别的集合合并到一起,类似于两棵树合并;查的意思就是找到这个点所属集合的根节点。基本上并查集题目都是在大体架构上面加一些东西即可。并查集代码模板在这里点击打开链接
这道题目和poj 1703 很相似,bug之间只存在两种状态,男 1 和女 0,所以两个被判断是同性的相恋就可疑了(德国人还挺好玩)。在这里这里在并查集模板里加入一个sex数组,用来说明这一个节点的bug是属于男还是女。我们在find_set和union_set的时候对sex进行处理,来保证该点和前驱结点不同,而和前驱结点的前驱结点相同。
#include<stdio.h>
const int MAXN = 2005;
int pa[MAXN];
int sex[MAXN];
int n;
void make_set(int size)
{
int i;
for(i=1;i<=size;i++){
pa[i] = i;
sex[i]= 0;
}
}
int find_set(int x)
{
int temp;
if(x==pa[x])
return x;
temp = pa[x];
pa[x]=find_set(temp);
sex[x]=(sex[temp]+sex[x])%2;
return pa[x];
}
void union_set(int x,int y)
{
int xx,yy;
xx=find_set(x);
yy=find_set(y);
pa[yy]=xx;
sex[yy]=(sex[x]+1-sex[y])%2;
}
int main()
{
int i=0,T,j,d,count=1,flag = 0;
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&d);
make_set(n);
while(d--){
scanf("%d %d",&i,&j);
if(find_set(i) == find_set(j)){
if(sex[i]==sex[j])
flag = 1;
}
if(flag == 0) union_set(i,j);
}
printf("Scenario #%d:\n",count);
if(flag == 0)printf("No suspicious bugs found!\n\n");
else printf("Suspicious bugs found!\n\n");
flag = 0;
count+=1;
}
return 0;
}