题意:将n个人分组,找出受感染的人有多少,当一个人感染,他所在的那一组均视为受感染。
分析:运用并查集将相关联的人都分到一个集合,然后判断每个人是否和0在同一个集合,若在则视为受感染,否则不是
#include<stdio.h> const int MN=30010; int father[MN],rank[MN],a[MN]; void init(int n) { for (int i=0;i<n;i++) { father[i]=i; rank[i]=1;//这个竟然忘记了,导致wa了3,4次 } } int Find(int x) { int r=x; while(r!=father[r]) { r=father[r]; } if(r!=x) father[x]=r; return r; } void Union(int x,int y) { if(x==y) return ; if(rank[x]>rank[y]) rank[y]=x; else { if(rank[x]==rank[y]) rank[x]++; else rank[y]++; father[x]=y; } } int main() { int n,m,i,k,j,ans; while(1) { scanf("%d%d",&n,&m); if(n==0 && m==0) break; init(n); ans=1;//记录人数 for (i=0;i<m;i++) { scanf("%d",&k); for (j=0;j<k;j++) { scanf("%d",&a[j]); } if(k==1) continue; for (j=1;j<k;j++)//并集合 { int x=Find(a[j-1]); int y=Find(a[j]); Union(x,y); } } father[0]=Find(father[0]); for (j=1;j<n;j++)//找出和0同在一集合的人数 { father[j]=Find(father[j]); if(father[0]==father[j]) ans++; } // int t1,t2; // for (t1=0;t1<3;t1++) // { // printf("%d ",father[i]); // } printf("%d\n",ans); } return 0; }