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
C++
#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);
}
}