1107 Social Clusters (30 分)
思路
经典并查集
int findFather(int x) //这里其实可以加入路径压缩
就是构造找爸爸时的树更矮一点
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int father[N]; //存放父亲结点
int isRoot[N] ={
0}; //记录每个结点是否作为某个集合的根结点
int course[N] = {
0}; //记录前面谁喜欢这个活动,然后和它合并
void init(int n ){
//初始化,每个人的爸爸是自己
for(int i =1 ;i<=n;i++){
father[i] = i;
}
}
int findFather(int x) //这里其实可以加入路径压缩
{
while(x!=father[x]){
x = father[x];
}
return x;
}
void Union(int a,int b) //实际上是合并爸爸
{
int faA = findFather(a);
int faB = findFather(b);
if(faA != faB)
father[faA] = faB;
}
int main(){
int n ,k,h;
char ch;
scanf("%d",&n);
init(n);
for(int i=1;i<=n;i++)
{
scanf("%d%c",&k,&ch);
for(int j =0;j<k;j++)
{
scanf("%d",&h);
if(course[h]==0)
course[h]= i;
Union(i,course[h]);
}
}
for(int i =1;i<=n;i++)
isRoot[findFather(i)]+=1;
int ans = 0;
for(int i =1;i<=n;i++)
if(isRoot[i]!=0)
ans++;
cout<<ans<<endl;
sort(isRoot,isRoot+n+1);
for(int i=n;i>=n-ans+1;i--)
{
if(i==n-ans+1)cout<<isRoot[i]<<endl;
else cout<<isRoot[i]<<" ";
}
}