有很多组学生,在同一个组的学生经常会接触,也会有新的同学的加入。但是SARS是很容易传染的,只要在改组有一位同学感染SARS,那么该组的所有同学都被认为得了SARS。现在的任务是计算出有多少位学生感染SARS了。假定编号为0的同学是得了SARS的。我们使用并查集来做这一题;
注意set 和find_set函数这是并查集的核心代码以后再做此类问题就可以模仿这两个模板;
#include<stdio.h> int num[30005],rank[30005],pa[30005]; void set(int a) { pa[a]=a; rank[a]=0; num[a]=1; } int find_set(int a) { int r=a,temp; while(pa[r]!=r) r=pa[r]; while(a!=r) { temp=pa[a];pa[a]=r; a=temp; } return a; } void union_set(int x,int y) { x = find_set(x); y = find_set(y); if(x == y)return ; if(rank[x] > rank[y])/*让rank比较高的作为父结点*/ { pa[y] = x; num[x] += num[y]; } else { pa[x] = y; if(rank[x] == rank[y]) rank[y]++; num[y] += num[x]; } } int main() { int n,m,i,j,k,p,t,u,x,y; while(scanf("%d %d",&n,&m)) { if(n==0&&m==0) break; if(m==0) { printf("1\n"); continue; } for(i=0;i<n;i++) set(i); for(i=0;i<m;i++) { scanf("%d",&t); scanf("%d",&p); for(j=1;j<t;j++) { scanf("%d",&u); union_set(p,u); p=u; } } p=find_set(0); printf("%d\n",num[p]); } return 0; }