7-7 社交集群 (30 分)
当你在社交网络平台注册时,一般总是被要求填写你的个人兴趣爱好,以便找到具有相同兴趣爱好的潜在的朋友。一个“社交集群”是指部分兴趣爱好相同的人的集合。你需要找出所有的社交集群。
输入格式:
输入在第一行给出一个正整数 N(),为社交网络平台注册的所有用户的人数。于是这些人从 1 到 N 编号。随后 N 行,每行按以下格式给出一个人的兴趣爱好列表:
: ...
其中是兴趣爱好的个数,是第个兴趣爱好的编号,为区间 [1, 1000] 内的整数。
输出格式:
首先在一行中输出不同的社交集群的个数。随后第二行按非增序输出每个集群中的人数。数字间以一个空格分隔,行末不得有多余空格。
输入样例:
8 3: 2 7 10 1: 4 2: 5 3 1: 4 1: 3 1: 4 4: 6 8 1 5 1: 4
输出样例:
3 4 3 1
#include<bits/stdc++.h> using namespace std; int f[21321]; int getf(int x) { if(x==f[x])return x; else { f[x] = getf(f[x]); return f[x]; } } void Merge(int aa,int bb) { int a = getf(aa); int b = getf(bb); if(a!=b) { f[a] = b; } } vector<int>o[123213]; int main() { for(int i=0;i<=12990;i++) { f[i] = i; } int n,num; cin>>n; int k; for(int i=1;i<=n;i++) { scanf("%d:",&k); for(int j=1;j<=k;j++) { cin>>num; o[num].push_back(i); } } for(int i=1;i<=1000;i++) { if(o[i].size()>1) { int pre =o[i][0]; for(int j=1;j<o[i].size();j++) { Merge(pre,o[i][j]); pre = o[i][j]; } } } int p[2000]={0}; int sum = 0; for(int i=1;i<=n;i++) { if(f[i]==i) { sum++; } int y = getf(i); p[y]++; } cout<<sum<<endl; vector<int>kk; for(int i=1;i<=n;i++) { if(p[i]!=0) { kk.push_back(p[i]); } } sort(kk.begin(),kk.end(),greater<int>( ) ); int top = 1; for(int ii:kk) { if(top)top=0; else printf(" "); printf("%d",ii); } }