D

题意

  有n个人编号从0到n-1,有m个小组,输入m行,每行一个k代表本组人数,后面k个数字为本组人员编号。0号人是感染者,通过组能和0号人接触的人都会被感染,求总感染人数。

思路

  把每组人都用并查集合并起来,然后从0到n-1看每个人的老大是否和0号人的老大相同,相同证明在一颗树里面,即题意的接触,ans++。

AC代码

#include<iostream>
using namespace std;
const int maxn=3e4+5;
int n,m,k;
int a,b;
int pre[maxn];

int find(int x){
    return (x==pre[x])?x:pre[x]=find(pre[x]);
}
void merge(int x,int y){
    int fx=find(x),fy=find(y);
    if(fx!=fy)
        pre[fy]=fx;
}

int main()
{
    while(cin>>n>>m){
        if(n==0&&m==0) break;
        int ans=0;
        for(int i=0;i<n;i++) pre[i]=i;
        while(m--){
            ans=0;
            cin>>k;
            if(k) cin>>a;
            for(int i=1;i<k;i++){
                cin>>b;
                merge(a,b);
            }
        }
        for(int i=0;i<n;i++){
            if(find(i)==find(0)) ans++;
        }
        cout<<ans<<'
';
    }
    return 0;
}
原文地址:https://www.cnblogs.com/qq2210446939/p/12765733.html