hdu1856--------------并查集+树

一次AC,受宠若惊啊!呵呵,一看数据   1<=n<=10000000,感觉有点大,很担心超时。题目要求求出最大集合的元素个数。

 

思想是并查集,不会错。有人用了压缩路径的方法,我估计他也是怕在最后遍历时,求元素的根超时。我不太熟悉压缩路径,就在另设置了一个数组  

 root[10000000], 用来存储以  i  为根的集合的元素个数。这样一来,在每次合并两棵树时,将两棵数的集合元素个数相加存放在  root[i]中。

并设置全局变量 max,每次将新树的元素个数与  max  比大小。  最后输出  max   即为结果。        342

AC代码:

#include
int set[10000001];
int root[10000001];         //root[i]代表以i为根的树的节点
int max;
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,num;
 fx=find(x);
 fy=find(y);
 if(fx!=fy)          //根不同,就要合并
 {
  if(fx  {
   set[fy]=fx;
   root[fx]=root[fx]+root[fy];
   if(root[fx]>max)
   max=root[fx];
  }
  else
  {
   set[fx]=fy;
   root[fy]=root[fx]+root[fy];
   if(root[fy]>max)
   max=root[fy];
  }
   
 }
}
int main()
{
 int m,i,j;
 int x,y;
 while(scanf("%d",&m)!=EOF)
 {
  if(m==0)
  {
   printf("1\n");
   continue;
  }
  for(i=1;i<=10000000;i++)
  {
   set[i]=i;
   root[i]=1;
  }
  max=0;
  for(i=1;i<=m;i++)
  {
   scanf("%d%d",&x,&y);
   merge(x,y);
  }
  printf("%d\n",max);
 }
 return 0;
}

转载于:https://www.cnblogs.com/zhangyabin---acm/archive/2012/03/10/2388888.html

你可能感兴趣的:(hdu1856--------------并查集+树)