hdu 1856求集合中元素个数

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1856
这道题目的目的是想知道经过一系列的合并操作之后,查询在所有的子树中,秩的最大值是多少,简而言之,就是最大的那颗子树包含了多少个节点。
很显然,这个问题也能够同时使用两种优化策略,只不过因为要求最大秩的值,需要有一个变量来记录。那么在哪个地方来更新它是最好的呢?我们知道,在按秩进行合并的时候,需要比较两颗待合并子树的秩,因此可以顺带的将对秩的最大值的更新也放在这里进行

/*不是求有几个集合,而是求每个集合中元素的个数,进而求出个数的最大值。
和求集合个数的方法差不多,只需要在合并两个集合时处理一下,让这两个集合的元素个数也合并一下就行了。
接下来只需要找出最大值即可。要注意的一个地方就是:当n=0时,要输出1。
*/

#include
#define N 10000000
int father[N],num[N];
void initial()/*初始化*/
{
    int i;
    for(i=1;i<=N;i++)
    {
        father[i]=i;
        num[i]=1;/*开始时数量都为1,根节点为自己*/
    }
}
int find(int x) /*寻找根节点*/
{
    if(father[x]!=x)
        father[x]=find(father[x]);
    return father[x];
}
void merge(int a,int b)/*合并a和b*/
{
    int p=find(a);
    int q=find(b);
    if(p!=q)
    {
        father[p]=q;
        num[q]+=num[p];/*合并集合中元素个数*/
    }
}
int main()
{
    int n,a,b,i,sum,max;
    while(~scanf("%d",&n))
    {
        if(n==0)
        {
            printf("1\n");
            continue;
        }
        max=0;
        initial(); /*初始化*/
        for(i=0;iscanf("%d%d",&a,&b);
            if(a>max)
                max=a;
            if(b>max)
                max=b;
            merge(a,b); /*合并集合*/
        }
        int Max=0;
        for(i=1;i<=max;i++)
            if(num[i]>Max) /*查找最大值*/
                Max=num[i];
        printf("%d\n",Max);
    }
    return 0;
}

你可能感兴趣的:(ICPC,Disjoint并查集)