hdu1829------------------并查集
题目大意:Hopper教授正在研究一种稀有虫子的交配行为。他假设它们有两种性别并且它们只与异性交配。在他的实验中,很容易识别虫子和它们的交配行为,因为虫子背后印有编号。
问题
给定一组虫子的交配行为,确定实验是支持教授的假设即虫子没有同性恋,还是有部分交配行为不符合假设。
这道题实际上还是并查集,和以往不同的是。以往给出两个元素的关系,然后认为这两个元素有联系,把它们划归为同一个集合。 最后看看能划分出多少个不同的集合。 本道题,可以认为有两个集合,异性和同性。 给出关系,希望你检查这两个集合有没有连接,即有没有同性恋。
大体思路: ‘合并’操作, ‘查找’操作不变。设置一个sex[] 数组,sex[i]存储与 i 性别相反的对象编号 ,初始化为0 。 然后将于i 发生联系的元素合并为同一个集合(因为人为它们是同性)。下次输入x,y时,如果 find(x)==fidn(y),我们就可以人为出现了反常行为。
总之,就是将同性的化为同一个集合中去。
#include<stdio.h>
#include<string.h>
int set[2005];
int sex[2005];
int temp;
int find(int x) //查找
{
int r;
r=x;
while(set[r]!=r)
r=set[r];
return r;
}
int merge(int x,int y) //合并
{
int fx,fy;
fx=find(x);
fy=find(y);
if(fx!=fy)
{
if(fx<fy)
set[fy]=fx;
if(fx>fy)
set[fx]=fy;
}
}
int main()
{
int x,y,n,m,i,j;
int t,count=0;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=0;i<=n;i++)
{
set[i]=i;
sex[i]=0; //sex[i]存储与i性别相反的对象编号 ,初始化为0
}
temp=0; //假设没有
count++;
while(m--)
{
scanf("%d%d",&x,&y);
if(find(x)==find(y)) //如果发现他们是同一个集合,则说明有同性恋
{
temp=1;
}
else //如果不相等,就行判断
{
if(sex[x]==0)
sex[x]=y;
else
merge(sex[x],y); //说明sex[x],y是同性,把它们联系起来! 下次就可以一下子找出它们
if(sex[y]==0)
sex[y]=x;
else
merge(sex[y],x);
}
}
printf("Scenario #%d:\n",count);
if(temp==1)
printf("Suspicious bugs found!\n");
else
printf("No suspicious bugs found!\n");
printf("\n");
}
return 0;
}