In the Not-Spreading-Your-Sickness University (NSYSU), there are many student groups. Students in the same group intercommunicate with each other frequently, and a student may join several groups. To prevent the possible transmissions of SARS, the NSYSU collects the member lists of all student groups, and makes the following rule in their standard operation procedure (SOP).
Once a member in a group is a suspect, all members in the group are suspects.
However, they find that it is not easy to identify all the suspects when a student is recognized as a suspect. Your job is to write a program which finds all the suspects.
A case with n = 0 and m = 0 indicates the end of the input, and need not be processed.
100 4 2 1 2 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
4 1 1
题意:非典传染给出n个人,m组人,规定0号人为非典的携带者,与他一组的人都将感染
m组人中输入第一个数为k,表示这组的人数
代码:
#include<stdio.h>
#include<string.h>
#define MAX 30050
int n,m;
int mark[MAX],pre[MAX]; // mark 数组 用来标记数字是否出现过
void init(int n){
int i;
for(i=0;i<=n;i++)
pre[i]=i;
}
int Find(int x){
int r=x;
while(r!=pre[r])
r=pre[r];
int i=x,j;
while(i!=r){
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
void mix(int a,int b){
int fa=Find(a),fb=Find(b);
if(fa!=fb){
if(fa==0) pre[fb]=fa; //优先归并到 0 结点
else pre[fa]=fb;
}
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
int w=0;
mark[0]=1;
init(MAX);
memset(mark,0,n+1);
if(n==m&&n==0) break;
while(m--){
int k;
scanf("%d",&k);
int t;
scanf("%d",&t);
if(mark[t]==0)
mark[t]=1;
int ft=Find(t);
while(k>1){
scanf("%d",&t);
if(mark[t]==0)
mark[t]=1;
mix(t,ft);
k--;
}
}
int i;
int cnt=1;
for(i=1;i<=n;i++){
if(Find(i)==0) //注意不能用pre 数组 会出错
cnt++;
}
printf("%d\n",cnt);
}
return 0;
}