hdu1856--------------并查集+树
一次AC,受宠若惊啊!呵呵,一看数据 1<=n<=10000000,感觉有点大,很担心超时。题目要求求出最大集合的元素个数。
思想是并查集,不会错。有人用了压缩路径的方法,我估计他也是怕在最后遍历时,求元素的根超时。我不太熟悉压缩路径,就在另设置了一个数组
root[10000000], 用来存储以 i 为根的集合的元素个数。这样一来,在每次合并两棵树时,将两棵数的集合元素个数相加存放在 root[i]中。
并设置全局变量 max,每次将新树的元素个数与 max 比大小。 最后输出 max 即为结果。 342
AC代码:
#include<stdio.h>
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<fy)
{
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;
}