简单的并查集问题,引入计数数组num来记录该根节点的对应的集之中的人数,刚开始时num均为1。
逐次将团体编号输入到并查集中,最后找到0的根结点,输出对应的num值。
TIP:题目数据有可能给出两个相同的集合合并,所以合并时要加上 if(a==b) return; 否则WA。
#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
int n;
struct UFS
{
int father[40000],rank[40000],num[40000];
UFS(int n)
{
for(int i=0; i<n; i++)
{
father[i]=i;
rank[i]=0;
num[i]=1;
}
}
int find(int v)
{
return father[v]=father[v]==v?v:find(father[v]);
}
void merge(int x,int y)
{
int a=find(x),b=find(y);
if(a==b) return;
if(rank[a]<rank[b])
{
father[a]=b;
num[b]+=num[a];
}
else
{
father[b]=a;
num[a]+=num[b];
if(rank[a]==rank[b])
++rank[a];
}
//if(a==0||b==0) cout<<"----------"<<endl;
}
};
int main()
{
int m,t,x,y;
while(cin>>n>>m)
{
if(m==0&&n==0) break;
UFS u1(n);
for(int i=0; i<m; i++)
{
cin>>t;
if(t==0) continue;
cin>>x;
for(int j=1; j<t; j++)
{
cin>>y;
u1.merge(x,y);
x=y;
}
}
int ans=u1.find(0);
cout<<u1.num[ans]<<endl;
}
return 0;
}