hdu1272---------------------并查集 + 判联通

这道题给出了一些点和边的信息,让你判断是否能够组成一个无环的联通集合,且这个唯一的集合可以为空。

你需要做:1,判是否成环,     只要输入的边的两个点有共同的父节点,那么着两个点就成环了。

              2,判联通,          只要最后判断根节点的总数为1即可。

这道题花了我一上午,WA了5次。

前两次是我不知道判联通,该! 后几次是太粗心了,初始化该写100000,却写成了10000!  累死我了,怎么也找不出原因!唉,悲剧啊

注意若只输入0  0,则输出Yes

AC代码:

#include<stdio.h>
int set[100005];
int flag[100005];
int temp;

int find(int x)
{
 int r;
 r=x;
 while(set[r]!=r)
 r=set[r];
 return r;
}
void merge(int x,int y)
{
 int fx,fy;
 fx=find(x);
 fy=find(y);
 if(fx==fy)                //表示有环
 temp=0;
 if(fx!=fy)
 {
  if(fx<fy)
  set[fy]=fx;
  else
  set[fx]=fy;
 }
}
int main()
{
 int i,j,count;
 int x,y;
 while(scanf("%d%d",&x,&y)!=EOF&&x!=-1)
 {
  if(x==0)
  {
   printf("Yes\n");
         continue;
  }
  
  for(i=1;i<=100001;i++)
  {
   flag[i]=0;
   set[i]=i;
  }
  temp=1;                     //初始化,表示可以
  flag[x]=1;         //表示这个点被访问过
  flag[y]=1;
  merge(x,y);
  while(scanf("%d%d",&x,&y)!=EOF&&x!=0)
  {
   merge(x,y);
   flag[x]=1;
   flag[y]=1;
  }
  count=0;
  for(i=1;i<=100001;i++)
  {
   if(flag[i]&&set[i]==i)
   count++;
  }
  
  if(count>1)            //判联通,若这些点是一个集合,则根节点只有一个
  temp=0;
  if(temp==1)
  printf("Yes\n");
  if(temp==0)
  printf("No\n");
 }
 return 0;
}

posted on 2012-03-09 13:56  hrbust_09zhangyabin  阅读(227)  评论(0编辑  收藏  举报