并查集初步应用,还不是很熟练。并查集两个主要函数:Union和Find。Union通常把两条不连通的支路使其连通;Find用来查找根节点,必要的要进行路径压缩。
大致题意:0号学生是默认的感染者,在M组团体中,如果出现了0号,则整个团体都是感染者。
样例:
Sample Input
100 4 //第一行两个整数N,M,表示N个学生(已编号0~N-1),M个团体 (0 < N <= 30000,0 <= M <= 500)
2 1 2 //以下M行,第一个数是该团体的人数K 后面是K个学生的编号
5 10 13 11 12 14
2 0 1
2 99 2
200 2
1 5
5 1 2 3 4 5
1 0
0 0
Sanple Output(输出每组案例的感染者数目)
4
1
1
1 #include<iostream> 2 using namespace std; 3 4 int node[30001],flag[30001]; 5 int n,m,num; 6 7 void Init(int n)//初始化 8 { 9 for(int i=0;i<n;i++) 10 node[i]=i; 11 } 12 13 int find(int x)//查找x的父节点 14 { 15 if(node[x]==x)//父节点是它本身 16 return x; 17 else//往上找 18 return node[x]=find(node[x]); 19 } 20 21 22 void mix(int x,int y)//使x和y连通 23 { 24 x=find(x); 25 y=find(y); 26 node[x]=y; 27 } 28 29 int main() 30 { 31 int i; 32 while((cin>>n>>m)&&n*n+m*m) 33 { 34 Init(n); 35 while(m--) 36 { 37 cin>>num; 38 for(i=0;i<num;i++) 39 cin>>flag[i]; 40 for(i=1;i<num;i++) 41 mix(flag[i-1],flag[i]);//把输入的各点连通 42 } 43 int c=0; 44 for(i=0;i<n;i++) 45 { 46 if(find(i)==find(0))//判断父节点是否与一号感染者相同 47 c++; 48 } 49 cout<<c<<endl; 50 } 51 return 0; 52 }