题目链接
https://pintia.cn/problem-sets/994805342720868352/problems/994805361586847744
题解
题目要求
- 输入
- N:正整数,不超过1000,人的数量,索引为[1,N]
- N个人的爱好:爱好的索引为[1,1000]
- 输出
- 有几个类(如果两人有共同爱好,则他们属于同一类)
- 每类的人数
解题思路
代码
// 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
", 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/
欢迎讨论和交流!