poj 1611(并查集)
http://poj.org/problem?id=1611
题意:有个学生感染病毒了,只要是和这个学生接触过的人都会感染,而和这些被感染者接触的人,也会被感染,现在给定你一些协会的人数,以及所在学生的编号,要你求被感染的人数。
思路:首先,把同一个社团的人,合并到一个这个社团的第一个人的那里,并用一个数组记录这个集合有多少人,最后查找0这个元素在哪个集合就可以。
1 #include <stdio.h> 2 #include <string.h> 3 #define l 30005 4 5 int belg[l],num[l]; 6 7 int Find(int x) 8 { 9 int _x=x,_b; 10 while(_x!=belg[_x]) 11 { 12 _x=belg[_x]; 13 } 14 while(x!=belg[x]) 15 { 16 _b=belg[x]; 17 belg[x]=_x; 18 x=_b; 19 } 20 return _x; 21 } 22 23 void unio (int x,int y) 24 { 25 int root1=Find(x); 26 int root2=Find(y); 27 if(root1!=root2) 28 { 29 belg[root1]=root2; 30 num[root2]+=num[root1]; //合并的时候,记得把人数也合并。 31 } 32 } 33 34 int main() 35 { 36 int m,n,a,b,c; 37 // freopen("in.txt","r",stdin); 38 while(scanf("%d%d",&m,&n)) 39 { 40 if(m==n&&m==0) break; 41 if(m==0) printf("1\n"); 42 for(int i=0;i<m;i++) 43 { 44 belg[i]=i; 45 num[i]=1; 46 } 47 for(int i=0;i<n;i++) 48 { 49 scanf("%d%d",&a,&b); 50 for(int i=1;i<a;i++) 51 { 52 scanf("%d",&c); 53 unio(b,c); 54 b=c; 55 } 56 } 57 printf("%d\n",num[Find(0)]); 58 } 59 return 0; 60 }