题目翻译
在一些社交网络平台上注册账号时,平台总是会要求你填写自己的兴趣爱好,以便找到一些具有相同兴趣爱好的潜在朋友。
社会集群是指一群有共同爱好的人。
给定社交网络中所有人的兴趣爱好,请你找到所有社会群集。
输入格式
第一行包含一个正整数 N,表示社交网络的人数,所有人的编号为 1∼N。
接下来 N 行,每行包含一个人的爱好信息,格式:Ki: hi[1] hi[2] … hi[Ki]
,Ki 表示爱好数量,hi[j] 表示第 j 个爱好的编号。
输出格式
第一行输出总集群数量。
第二行按非递增顺序输出每个集群的人数。
数字之间空格隔开,行尾不得有多余空格。
数据范围
1 ≤ N ≤ 1000,Ki > 0,
爱好种类最多 1000 种,编号范围 [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 <vector>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
char c;
int n, k;
vector<int> g[N];
int p[N], cnt[N], ans[N];
int find(int x)
{
if(p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i ++)
{
cin >> k >> c;
while(k --)
{
int x;
cin >> x;
g[x].push_back(i);
}
}
for (int i = 1; i <= n; i ++) p[i] = i;
for (int i = 1; i <= 1000; i ++)
for (int j = 1; j < g[i].size(); j ++)
{
int a = g[i][0], b = g[i][j];
p[find(b)] = find(a);
}
for (int i = 1; i <= n; i ++) cnt[find(i)] ++;
k = 0;
for (int i = 1; i <= n; i ++)
if(cnt[i]) ans[k ++] = cnt[i];
sort(ans, ans + k);
reverse(ans, ans + k);
cout << k << endl;
cout << ans[0];
for (int i = 1; i < k; i ++) cout << ' ' << ans[i];
return 0;
}