The meaning of the question
: Now is the period of influenza outbreak, the school has n students, the student number is 0~n-1, and there are m clubs. Student No. 0 is a virus carrier. If there is a student and a virus carrier in the same club, then he will also become a virus carrier. For example, community 1 (0, 1, community 2 (1, 2, 3), then 0, 1, 2, and 3 are all virus carriers.
Given the number of students and clubs, ask how many virus carriers there are.
Idea
: It is enough to use union search to merge sets, and treat each community as a set and merge. Finally, find the root node of the set where student No. 0 is located, and then traverse all students. If it is the same as the root node of student No. 0, it means that they are in a set.
/// Carefully understand the Find() operation! ! #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include <string> using namespace std; int rk[30005],par[30005]; int a[30005]; int n,years; void init()//initialization { for(int i=0;i<n;i++){ rk[i]=0; par [i] = i; } } int Find(int x)//Find the root node { while(x!=par[x]) x=by[x]; return x; } void unite(int x, int y)//Merge collection { x=Find(x); y=Find(y); if(x==y) return ; if(rk[x]<rk[y]) by[x]=y; else{ by[y]=x; if(rk[x]==rk[y]) rk[x]++; } } intmain() { int m,x; int a,b; while(~scanf("%d%d",&n,&m)&&(n+m)){ init(); for(int i=0;i<m;i++){ scanf("%d",&x); scanf("%d",&a);//Merge the first person of each community as the root node of the community for(int j=1;j<x;j++){ scanf("%d",&b); unite(a,b); } } years=1; for(int i=1;i<n;i++){//Find students who are in the same set as student No. 0 if(Find(i)==Find(0)) years++; } printf("%d\n",ans); } }