http://poj.org/problem?id=1611
并查集就意味着对于联通分量的完美运用
开一个num数组可以记录子孙节点个数
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define maxn 30090
int n,m;
int fa[maxn];
int num[maxn];
int find(int x)
{
int f=fa[x];
while(f!=fa[i])// 一开始写成 if(f!=fa[f])结果还以为是路径压缩错了
{
f=fa[f];
}
int j;
/* while(x!=f)
{
j=fa[x];
num[j]-=num[x];
fa[x]=f;
x=j;
}*///1.不用压缩也一样2.注意num更新必须在x变化之前!!3.num【f】不必更新
return f;
}
void makeset(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx!=fy)
{
fa[fx]=fy;
num[fy]+=num[fx];
}
}
int main()
{
while(scanf("%d %d",&n,&m)&&(n||m))
{
int i;
for(i=0;i<n;i++)
{
fa[i]=i;
num[i]=1;
}
for(i=0;i<m;i++)
{
int k,u;
scanf("%d %d",&k,&u);
int j,p;
for(j=1;j<k;j++)
{
scanf("%d",&p);
makeset(p,u);
}
}
printf("%d\n",num[find(0)]);
}
return 0;
}