http://acm.hdu.edu.cn/showproblem.php?pid=1856
//题意:一个人选了一些人在房间里,然后给定一些关系,代表两个人是朋友,问最多有多少人能留在房间里,能留在房间里的人相互之间是朋友。
这道题目的目的是想知道经过一系列的合并操作之后,查询在所有的子树中,秩的最大值是多少,简而言之,就是最大的那颗子树包含了多少个节点。
很显然,这个问题也能够同时使用两种优化策略,只不过因为要求最大秩的值,需要有一个变量来记录。那么在哪个地方来更新它是最好的呢?我们知道,在按秩进行合并的时候,需要比较两颗待合并子树的秩,因此可以顺带的将对秩的最大值的更新也放在这里进行. 注意当n为0 时,输出为1 。
#include<cstdio>
#define N 100001
int father[N],sz[N],max;
int find(int x)
{
if(x==father[x]) return x;
father[x]=find(father[x]);
return father[x];
}
void Union(int x,int y)
{
int a=find(x);
int b=find(y);
if(a==b) return;
if(sz[a]>sz[b])
{
father[b]=a;
sz[a]+=sz[b];
if(sz[a]>max)
{
max=sz[a];
}
}
else
{
father[a]=b;
sz[b]+=sz[a];
if(sz[b]>max)
max=sz[b];
}
}
int main()
{
int n,a,b,i;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
{
father[i]=i;
sz[i]=1;
}
max=1; //输入0 时输出是 1
for(i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
Union(a,b);
}
printf("%d\n",max);
}
return 0;
}