poj1611 并查集 (路径不压缩)

Posted a_clown_cz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj1611 并查集 (路径不压缩)相关的知识,希望对你有一定的参考价值。

http://poj.org/problem?id=1611

题目大意:

有一个学校,有N个学生,编号为0-N-1,现在0号学生感染了非典,凡是和0在一个社团的人就会感染,并且这些人如果还参加了别的社团,他所在的社团照样全部感染,求感染的人数。

 

解题思路:

并查集的变种,实质就是求0所在的强连通图的结点数目。

这道题纠结在数据的输入上,他只是告诉你哪些学生是同一个社团的。这就需要处理一下,我的想法是:如果这个社团有num个孩子,new出一个大小为num的数组,第一个孩子不处理,从第二个孩子起,和上个孩子合并,这样就完成了他们的合并。

 

AC代码:

#include<iostream>
#include<cstdio>
using namespace std;
int p[30005],b[30005],r[30005],num[30005];
int n,m,k;
int Find(int x)
{
    if(p[x]!=x) p[x]=Find(p[x]);
    return p[x];
}
void Union(int x,int y)
{
    //x=Find(x);
    //y=Find(y);
    if(x==y) return;
    if(r[x]>r[y])
    {
        p[y]=x;
        num[x]+=num[y];
    }
    else
    {
        p[x]=y;
        if(r[x]==r[y]);
        r[y]++;
        num[y]+=num[x];
    }
}
int main()
{
    while(scanf("%d%d",&n,&m)&&(m+n))
    {
        for(int i=0; i<n; i++)
        {
            p[i]=i;
            r[i]=0;
            num[i]=1;
        }
        while(m--)
        {
            scanf("%d",&k);
            for(int i=1; i<=k; i++)
                scanf("%d",&b[i]);
            for(int i=1; i<k; i++)
            {
                int x=Find(b[i]);
                int y=Find(b[i+1]);
                Union(x,y);
            }
        }
        int p=Find(0);
        printf("%d\n",num[p]);
    }
    return 0;
}

 

以上是关于poj1611 并查集 (路径不压缩)的主要内容,如果未能解决你的问题,请参考以下文章

poj 1611 The Suspects

poj1611(并查集简单应用)

poj1611 The Suspects(并查集)

POJ 1988 Cube Stacking(并查集+路径压缩)

POJ 1611---The Suspects(并查集)

POJ-1611(并查集)