这个题巧妙的运用了hab[a]来存输入的第一个爱好是a的人,这就把并查集和兴趣爱好分开来。然后就是经典的并查集模版使用Union的时候是Union(当前这个人,hab【a】喜欢a爱好的第一个人)。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 10100;
int fa[maxn], hab[maxn];
unordered_map<int, int> mp;
vector<int> ans;
int findFather (int a) {
int x = a;
while (a != fa[a]) {
a = fa[a];
}
while (x != fa[x]) {
int z = x;
x = fa[x];
fa[z] = a;
}
return a;
}
void Union (int a, int b) {
int faA = findFather(a);
int faB = findFather(b);
if (faA != faB) {
fa[faB] = faA;
}
}
void init () {
for (int i = 0; i < maxn; i++) fa[i] = i;
}
int main() {
int n, k, a;
scanf ("%d", &n);
init();
for (int i = 1; i <= n; i++) {
scanf ("%d:", &k);
for (int j = 0; j < k; j++) {
scanf ("%d", &a);
if (hab[a] == 0) hab[a] = i;
Union (i, hab[a]);
}
}
for (int i = 1; i <= n; i++) {
mp[findFather(i)]++;
}
for (auto it : mp) ans.push_back(it.second);
sort(ans.begin(), ans.end());
cout << ans.size() << endl;
for (int i = ans.size() - 1; i >= 0; i--) {
printf ("%d", ans[i]);
if (i != 0) printf (" ");
}
}