题意:
0号为默认嫌疑人,所有跟0号曾经在同一个分组的也会被视为嫌疑人,只要是跟嫌疑人在一组过的都视为嫌疑人。
思路:
将每一组并入同一个集合,然后找到所有跟0相同根节点的人就可以了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int fa[31000],te[31000];
int find(int h)
{
if (h!= fa[h])
{
fa[h] = find(fa[h]); //这个回溯时的压缩路径是精华
}
return fa[h];
}
void uni(int c1,int c2)
{
c1=find(c1) ;
c2=find(c2) ;
if(c1!=c2)
{
fa[c1]=c2 ;
}
}
int main(){
int n,m,k;
for(int i=1;i<1100;i++)
fa[i]=i;
while(scanf("%d%d",&n,&m),n||m){
for(int i=0;i<n;i++)
fa[i]=i;
for(int t=0;t<m;t++){
scanf("%d",&k);
for(int h=0;h<k;h++){
scanf("%d",&te[h]);
}
for(int i=0;i<k-1;i++)
uni(te[i],te[i+1]);
}
int co=0,de;
de=find(0);
for(int i=0;i<n;i++)
if(find(i)==de) co++;
printf("%d\n",co);
// for(int i=0;i<n;i++)
// printf("%d ",find(i));
}
return 0;
}
\