码迷,mamicode.com
首页 > 其他好文 > 详细

poj1611 并查集 (路径不压缩)

时间:2016-09-28 22:41:48      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:

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 并查集 (路径不压缩)

标签:

原文地址:http://www.cnblogs.com/a-clown/p/5918019.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!