PAT甲级1107Social Clusters

题目链接

https://pintia.cn/problem-sets/994805342720868352/problems/994805361586847744

题解

题目要求

  • 输入
    • N:正整数,不超过1000,人的数量,索引为[1,N]
    • N个人的爱好:爱好的索引为[1,1000]
  • 输出
    • 有几个类(如果两人有共同爱好,则他们属于同一类)
    • 每类的人数

解题思路

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// Problem: PAT Advanced 1107
// URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805361586847744
// Tags: 并查集 路径压缩

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> father, clusterSize;
int likeHobby[1001]; // 保存这一爱好的代表人(任意)

int findFather(int x){
return father[x] == x ? x : father[x] = findFather(father[x]); // 路径压缩
// return father[x] == x ? x : findFather(father[x]);
}

void UNION(int a, int b){
int fa = findFather(a), fb = findFather(b);
if (fa != fb)
father[fa] = fb;
}

bool cmp(int& a, int& b){
return a > b;
}

int main()
{
int n, k, hobby;
scanf("%d", &n);
father.resize(n+1);
clusterSize.resize(n+1);
for (int i = 0; i < father.size(); i++) // 初始化,每人都是一个cluster
father[i] = i;
for (int i = 1; i <= n; i++){
scanf("%d:", &k);
for (int j = 0; j < k; j++){
scanf("%d", &hobby);
if (likeHobby[hobby] == 0)
likeHobby[hobby] = i;
UNION(i, likeHobby[hobby]); // 将i和他的爱好的代表人合并
}
}

// 统计每个cluster的人数
for (int i = 1; i <= n; i++){
clusterSize[findFather(i)]++;
}
sort(clusterSize.begin(), clusterSize.end(), cmp);
int cnt = 0;
while (clusterSize[cnt] > 0){
cnt++;
}
printf("%d\n", cnt);
if (cnt > 0){
printf("%d", clusterSize[0]);
for (int i = 1; i < cnt; i++)
printf(" %d", clusterSize[i]);
}
return 0;
}

参考链接

https://zhuanlan.zhihu.com/p/93647900

https://blog.csdn.net/liuchuo/article/details/52191082


作者:@臭咸鱼

转载请注明出处:https://www.cnblogs.com/chouxianyu/

欢迎讨论和交流!