题目链接:http://poj.org/problem?id=2492
题目大意:每组测试数据给出n个虫子和m种交配组合,判断虫子中有没有同性交配的。
解决方案:首先大方向确定用并查集,每个虫子都初始化为一个集合。输入交配组合是,对每队虫子先判断他们是否在一个集合,如不在,则合并集合,若在,判断他们是否同性。判断方法为与祖先进行比较。
虽然思路很清楚,但要实现的好也不容易,花了一些时间去看别人的代码,然后才明白怎么实现才更好。
#include<stdio.h>
#include<stdlib.h>
#define Max 2001
int parent[Max];
int relations[Max]; //与父亲的关系,0代表同性
void Init(int n)
{
int i;
for(i = 0;i <= n;i ++){
parent[i] = i;
relations[i] = 0;
}
return;
}
int findSet(int x)
{
int temp = parent[x];
if(temp == x)
return x;
parent[x] = findSet(temp);
relations[x] = (relations[x] + relations[temp]) % 2; //由于之前可能已经发生了集合合并,祖先发生变动,所以要重新更新关系数组。对2取余后就可以代表与祖先的关系。
return parent[x];
}
void unionSet(int a, int b)
{
int root1 = findSet(a);
int root2 = findSet(b);
parent[root1] = root2;
relations[root1] = (relations[a]-relations[b] + 1)%2;
}
int main(void)
{
int i,t,n,m,a,b,flag,count;
scanf("%d",&t);
Init(Max - 1);
count = 1;
while(t --)
{
flag = 1;
scanf("%d %d",&n,&m);
for(i = 1;i <= m;i ++){
scanf("%d %d",&a,&b);
if(findSet(a) == findSet(b))
{
if(relations[a] != (relations[b] + 1) % 2) //如果不满足异性关系,有矛盾
flag = 0;
}
else
{
unionSet(a, b);
}
}
if(flag)
{
printf("Scenario #%d:\nNo suspicious bugs found!\n\n", count++);
}
else
{
printf("Scenario #%d:\nSuspicious bugs found!\n\n", count++);
}
Init(n);
}
return 0;
}