OJ:【PAT】1107 Social Clusters
思想:
1、读入数据集的同时,将同一爱好的人存入同一个vector中。
2、然后遍历不同的爱好vector,将他们一一求并集。
3、然后遍历并查集数组father[]统计一共有多少个集合,每个集合中有多少人。
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
int father[1004],cnt[1007];
map<int, vector<int> > mp;
unordered_map<int,int> mp1;
vector<int> ans;
int findFather(int x) {
int a = x;
while (father[x] != x) {
x = father[x];
}
while (father[a] != a) {
int z = a;
a = father[a];
father[z] = x;
}
return x;
}
void Union(int a, int b) {
int aF = findFather(a);
int bF = findFather(b);
if (aF != bF)
father[aF] = bF;
}
int main() {
int N; scanf("%d", &N);
for (int i = 1; i <= N; i++) father[i] = i;
//读入输入数据,并且将有同一爱好的人加入一个集合中。
for (int i = 1; i <= N; i++) {
int num,temp; scanf("%d:", &num);
for (int j = 0; j < num; j++) {
scanf("%d", &temp);
mp[temp].push_back(i);
}
}
//将同一个集合中的人都一一求并集
for (auto it = mp.begin(); it != mp.end(); it++) {
int len = it->second.size();
for (int i = 1; i < len; i++) {
Union(it->second[i], it->second[i-1]);
//father[it->second[i]] = father[it->second[0]];
}
}
int sum = 0;
for (int i = 1; i <= N; i++) {
if (father[i] == i) sum++;//统计有多少个集合
//一开始写错了,并不是每个元素i的father[i]值直指其父节点
mp1[findFather(father[i])]++;//集合中人数的统计
//mp1[father[i]]++;
}
cout << sum << endl;//输出有多少集合
for (auto it = mp1.begin(); it != mp1.end(); it++)
ans.push_back(it->second);
sort(ans.begin(), ans.end());
int len = ans.size();
cout << ans[len - 1];
for (int i = len - 2; i >= 0; i--) {
cout << " " << ans[i];
}
}