题意
有N个人,每个人喜欢若干项活动,如果两个人有任意一个活动相同,那么就称他们处于同一个社交网络(若A和B属于同一个社交网络,B和C属于同一个社交网络,那么A、B、C属于同一个社交网络)。求这N个人总共形成了多少个社交网络。
思路
如果A和B是好朋友,并且B和C是好朋友,那么A和C也是好朋友。本题中判断两个人是好朋友的条件为他们有公共喜欢的活动,因此不妨开一个数组hobby,其中
hobby[h]用以记录第一个喜欢活动h的人的编号,这样的话find(hobby[h])就是这个人所在的社交网络的根结点。于是,对当前读入的人的编号i和他喜欢的每一个活动h,只需要合并i与hobby[h]即可。
const int N=1010;
int p[N];
int cnt[N];
int hobby[N];
int n;
int find(int x)
{
if(x != p[x]) p[x]=find(p[x]);
return p[x];
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) p[i]=i,cnt[i]=1;
for(int i=1;i<=n;i++)
{
int k;
scanf("%d:",&k);
for(int j=0;j<k;j++)
{
int x;
scanf("%d",&x);
if(hobby[x] == 0)
hobby[x]=i;
else
{
int pa=find(i),pb=find(hobby[x]);
if(pa != pb)
{
p[pa]=pb;
cnt[pb]+=cnt[pa];
cnt[pa]=0;
}
}
}
}
vector<int> res;
for(int i=1;i<=n;i++)
if(cnt[i])
res.pb(cnt[i]);
cout<<res.size()<<endl;
sort(res.begin(),res.end(),greater<int>());
for(int i=0;i<res.size();i++)
if(i) cout<<' '<<res[i];
else cout<<res[i];
cout<<endl;
//system("pause");
return 0;
}