本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1597. 社会集群
原题传送:AcWing 1597. 社会集群
在一些社交网络平台上注册账号时,平台总是会要求你填写自己的兴趣爱好,以便找到一些具有相同兴趣爱好的潜在朋友。
社会集群是指一群有共同爱好的人。
给定社交网络中所有人的兴趣爱好,请你找到所有社会群集。
输入格式
第一行包含一个正整数 ,表示社交网络的人数。
所有人的编号为 。
接下来 行,每行包含一个人的爱好信息,格式如下:
…
表示爱好数量, 表示第 个爱好的编号。
输出格式
第一行输出总集群数量。
第二行按非递增顺序输出每个集群的人数。
数字之间空格隔开,行尾不得有多余空格。
数据范围
, , 爱好种类最多 种,编号范围 。
输入样例:
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
样例解释
共 个集群:
- 人集群 ,他们都有共同的爱好 。
- 人集群 ,其中 和 有共同的爱好 , 和 有共同的爱好 。
- 人集群 。
思路:
将各种爱好对应的人存入vector,然后遍历每种爱好,将同一种爱好的人合并至一个集合,最后统计集合的数量和每个集合的人数。
题解:
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int n;
vector<int> hobby[N];
int p[N];
int cnt[N];
int find(int x)
{
if(p[x] != x)
p[x] = find(p[x]);
return p[x];
}
int main()
{
scanf("%d", &n);
for(int i = 0; i < n; i++)
p[i] = i;
for(int i = 0; i < n; i++)
{
int cnt;
scanf("%d:", &cnt);
while(cnt--)
{
int h;
scanf("%d", &h);
hobby[h].push_back(i);
}
}
for(int i = 0; i < N; i++)
{
for(int j = 1; j < hobby[i].size(); j++)
{
int a = hobby[i][0], b = hobby[i][j];
p[find(a)] = find(b);
}
}
for(int i = 0; i < n; i++)
cnt[find(i)]++;
sort(cnt, cnt + n, greater<int>());
int k = 0;
while(cnt[k])
k++;
printf("%d\n", k);
printf("%d", cnt[0]);
for(int i = 1; i < k; i++)
printf(" %d", cnt[i]);
printf("\n");
return 0;
}