并查集
分组,合并分组。
将同一组的数字放在一起,选一个当做根,其余的作为子节点,则根相同的为一组。
#include<iostream>
using namespace std;
const int maxn=1e5+7;
int pre[maxn];
void init(int n)
{
for(int i=0; i<=n; i++)
pre[i]=i;
}
int find(int x)
{
int p,tmp;
p=x;
while(x!=pre[x])
x=pre[x];
while(p!=x) /// 路径压缩
{
tmp=pre[p];
pre[p]=x;
p=tmp;
}
return x;
}
void join(int x,int y)
{
int fx=find(x),fy=find(y);
if(fx!=fy)
pre[fx]=fy;
}
int main()
{
int n,m;
while(cin>>n>>m)
{
if(n==0&&m==0)
break;
init(n);
for(int i=1; i<=m; i++)
{
int a,b,k;
cin>>a;
for(int j=1; j<=a; j++)
{
if(j==1)
{
cin>>b;
k=find(b);
continue;
}
else
{
cin>>b;
join(k,b);
}
}
}
int k2=find(0),cnt=0;
for(int i=0; i<n; i++)
if(find(i)==k2)
cnt++;
cout<<cnt<<endl;
}
return 0;
}