题意
有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; }