#include <stdio.h>
#include <iostream>
using namespace std;
int pa[30001]; /*pa[x]表示x的父节点*/
int rank[30001]; /*rank[x]是x的高度的一个上界*/
int num[30001];/*num[]存储该集合中元素个数,并在集合合并时更新num[]即可*/
void make_set(int x)
{/*创建一个单元集*/
pa[x]=x;
rank[x]=0;
num[x]=1;
}
int find_set(int x)
{/*带路径压缩的查找*/
/*保存待查找的数*/
int r=x,temp;
/*找到根节点*/
while(pa[r]!=r)
r=pa[r];
while(x!=r)
{
temp=pa[x];
pa[x]=r;
x=temp;
}
return x;
}
/*按秩合并x,y所在的集合*/
void union_set(int x, int y)
{
x=find_set(x);
y=find_set(y);
if(x==y)return ;
pa[x]=y;
if(rank[x]==rank[y])
rank[y]++;
num[y]+=num[x];
}
int main()
{
int n,m,x,y,i,t,j;
while(scanf("%d%d",&n,&m)&&n>0)
{
if(m==0)
{
printf("1\n"); continue;
}
for(i=0;i<n;i++)
make_set(i);
for(i=0;i<m;i++)
{
scanf("%d",&t);
scanf("%d",&x);
for(j=1;j<t;j++)
{
scanf("%d",&y);
union_set(x,y);
x=y;
}
}
x=find_set(0);/*找到0所在的树的树根*/
printf("%d\n",num[x]);
}
return 0;
}
点击打开链接