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;
}

posted on 2012-03-10 10:58  hrbust_09zhangyabin  阅读(797)  评论(0编辑  收藏  举报