题意:病毒蔓延,现在有 n 个人,其中 0 号被认为可能感染,然后给出多个社交圈,如果某个社交圈里有人被认为可能被感染,那么所有这个社交圈里的人都被认为可能被感染,现在问有多少人可能被感染。
带权并查集,给每个集合加入这个集合的总人数,合并集合是一起合并就可以了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 using namespace std;
5
6 int n,fa[30005],num[30005];
7
8 void init(){
9 for(int i=0;i<n;i++){fa[i]=i;num[i]=1;}
10 }
11
12 int find(int x){
13 int r=x,t;
14 while(fa[r]!=r)r=fa[r];
15 while(x!=r){
16 t=fa[x];
17 fa[x]=r;
18 x=t;
19 }
20 return r;
21 }
22
23 int main(){
24 int m;
25 while(scanf("%d%d",&n,&m)!=EOF&&(n!=0||m!=0)){
26 init();
27 int i,j;
28 for(i=1;i<=m;i++){
29 int t,a,b;
30 cin>>t;
31 for(j=1;j<=t;j++){
32 cin>>a;
33 if(j==1)b=a;
34 else{
35 int x=find(a),y=find(b);
36 if(x!=y){
37 fa[x]=y;
38 num[y]+=num[x];
39 }
40 }
41 }
42 }
43 int x=find(0);
44 printf("%d\n",num[x]);
45 }
46 return 0;
47 }