题意:n个同学。序号为 0到n-1,序号为0的同学感染了病毒。与0同属一个集合的同学也被觉得感染了病毒
输出有多少个同学感染了病毒
分析:题目意思就是求0所在集合的元素个数,能够找与0祖先同样的个数,
也可用一个数组记录不同父节点的集合元素的个数。再输出以0的父节点为祖先的集合元素个数
#include<stdio.h> #include<string.h> int f[30010],r[30010]; int find(int a) { if(a!=f[a]) f[a]=find(f[a]); return f[a]; } void mix(int a,int b) { int x,y; x=find(a); y=find(b); if(x==y) //这里记得要推断一下,否则r数组元素可能加反复了 return ; if(r[x]>r[y]){ f[y]=x; r[x]+=r[y]; } else{ f[x]=y; r[y]+=r[x]; } } int main() { int i,k,n,m,a,b,s; while(scanf("%d%d",&n,&m)!=EOF){ if(m==0&&n==0) break; for(i=0;i<=n;i++){ f[i]=i; r[i]=1; } while(m--){ scanf("%d",&k); for(i=1;i<=k;i++){ scanf("%d",&a); if(i>1) mix(a,b); b=a; } } s=r[find(0)]; printf("%d ",s); } return 0; }
#include<stdio.h> #include<string.h> int f[30010]; int find(int a) { if(a!=f[a]) f[a]=find(f[a]); return f[a]; } void mix(int a,int b) { int x,y; x=find(a); y=find(b); if(x!=y) f[x]=y; } int main() { int i,k,n,m,a,b,s; while(scanf("%d%d",&n,&m)!=EOF){ if(m==0&&n==0) break; for(i=0;i<=n;i++) f[i]=i; while(m--){ scanf("%d",&k); for(i=1;i<=k;i++){ scanf("%d",&a); if(i>1) mix(a,b); b=a; } } s=1; a=find(0); for(i=1;i<n;i++) if(find(i)==a) s++; printf("%d ",s); } return 0; }