传送门
并查集的应用,一个数组记录爱好第一次出现在哪个下标的人,并查集将有相同爱好的人合并,记录大小
#include<bits/stdc++.h>
using namespace std;
const int N=1086;
int n;
int fa[N],v[N],siz[N];//v[N]记录爱好第一次出现的人的下标
int find(int x){
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
void merge(int x,int y){
x=find(x),y=find(y);
if(x==y) return;
fa[x]=y;
siz[y]+=siz[x];//记录并查集大小
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) fa[i]=i,siz[i]=1;//初始化
for(int i=1;i<=n;i++){
int k,x;
char c;
cin>>k>>c;
for(int j=0;j<k;j++){
cin>>x;
if(v[x]) merge(i,v[x]);//爱好已经出现则并入群体中
else v[x]=i;//爱好没有出现则记录
}
}
priority_queue<int,vector<int>,less<int> > q;
int ans=0;
//遍历记录群体个数和数量
for(int i=1;i<=n;i++){
int k=find(i);
if(i==k) ans++,q.push(siz[k]);
}
cout<<ans<<endl;
if(!q.empty()) cout<<q.top(),q.pop();
while(!q.empty()){
cout<<" "<<q.top();q.pop();
}
return 0;
}