题目大意:有N个人,每个人有一些兴趣,用编号1~1000的整数表示。具有相同兴趣的人被划分为一个社交群,求出社交群的总数和每个群的人数。
并查集问题,读入一个人的每个兴趣时,将该人和有当前兴趣的人进行并集操作。
AC代码:
#include <vector>
#include <algorithm>
#include <cstdio>
#include <set>
using namespace std;
int findParent(int index, vector<int> &parent)
{
while(parent[index] != index)
{
parent[index] = parent[parent[index]];
index = parent[index];
}
return index;
}
void unionElement(int a, int b, vector<int> &parent)
{
int aRoot = findParent(a, parent);
int bRoot = findParent(b, parent);
parent[aRoot] = bRoot;
}
int main()
{
int N;
scanf("%d", &N);
vector<int> parent(N), cnt(N, 0);
vector<int> hobby(1010, -1);
for (int i = 0; i < N; ++i)
parent[i] = i;
for (int i = 0; i < N; ++i)
{
int hobbyNum;
scanf("%d: ", &hobbyNum);
for (int j = 0; j < hobbyNum; ++j)
{
int hobbyIndex;
scanf("%d", &hobbyIndex);
if(hobby[hobbyIndex] > -1)
unionElement(i, hobby[hobbyIndex], parent);
else hobby[hobbyIndex] = i;
}
}
set<int> roots;
for (int i = 0; i < N; ++i)
{
int iParent = findParent(i, parent);
cnt[iParent]++;
roots.insert(iParent);
}
printf("%lu\n", roots.size());
sort(cnt.begin(), cnt.end(), greater<int>());
int printCnt = 0;
for (int i = 0; i < N; ++i)
{
if(cnt[i] > 0)
{
printf("%d", cnt[i]);
printCnt++;
if(printCnt < roots.size()) printf(" ");
}
}
return 0;
}