POj 1611 The Suspects

时间:2022-05-08
本文章向大家介绍POj 1611 The Suspects,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题意:将n个人分组,找出受感染的人有多少,当一个人感染,他所在的那一组均视为受感染。

分析:运用并查集将相关联的人都分到一个集合,然后判断每个人是否和0在同一个集合,若在则视为受感染,否则不是

#include<stdio.h>
const int MN=30010;

int father[MN],rank[MN],a[MN];

void init(int n)
{
    for (int i=0;i<n;i++)
    {
        father[i]=i;
        rank[i]=1;//这个竟然忘记了,导致wa了3,4次
    }
}

int Find(int x)
{
    int r=x;
    while(r!=father[r])
    {
        r=father[r];
    }
    if(r!=x)
        father[x]=r;
    return r;
}

void Union(int x,int y)
{
    if(x==y) return ;
    if(rank[x]>rank[y]) rank[y]=x;
    else
    {
        if(rank[x]==rank[y]) rank[x]++;
        else rank[y]++;
        father[x]=y;
    }
}

int main()
{
    int n,m,i,k,j,ans;
    while(1)
    {
        scanf("%d%d",&n,&m);
        if(n==0 && m==0) break;
        init(n);
        ans=1;//记录人数
        for (i=0;i<m;i++)
        {
            scanf("%d",&k);
            for (j=0;j<k;j++)
            {
                scanf("%d",&a[j]);
            }
            if(k==1) continue;
            for (j=1;j<k;j++)//并集合
            {
                int x=Find(a[j-1]);
                int y=Find(a[j]);
                Union(x,y);
            }    
        }
        father[0]=Find(father[0]);
        for (j=1;j<n;j++)//找出和0同在一集合的人数
        {
            father[j]=Find(father[j]);
            if(father[0]==father[j]) ans++;
        }
    //    int t1,t2;
    //    for (t1=0;t1<3;t1++)
    //    {
    //        printf("%d ",father[i]);
    //    }
        printf("%dn",ans);
    }
    return 0;
}