题目描述
When register on a social network, you are always asked to specify your hobbies in order to find some potential friends with the same hobbies. A social cluster is a set of people who have some of their hobbies in common. You are supposed to find all the clusters.
Input Specification:
Each input file contains one test case. For each test case, the first line contains a positive integer N (≤1000), the total number of people in a social network. Hence the people are numbered from 1 to N. Then N lines follow, each gives the hobby list of a person in the format:
Ki : hi[1] hi[2] ... hi[Ki]
where Ki(>0) is the number of hobbies, and hi[j] is the index of the j-th hobby, which is an integer in [1, 1000].
Output Specification:
For each case, print in one line the total number of clusters in the network. Then in the second line, print the numbers of people in the clusters in non-increasing order. The numbers must be separated by exactly one space, and there must be no extra space at the end of the line.
Sample Input:
8
3: 2 7 10
1: 4
2: 5 3
1: 4
1: 3
1: 4
4: 6 8 1 5
1: 4
Sample Output :
3
4 3 1
考点
并查集
思路
并查集中存储的依然是人的编号,用course[h]表示任意一个喜欢h活动的人的编号。
代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> parent, isRoot;
int cmp1(int a, int b) { return a > b; }
int find(int x) {
int a = x;
while (x != parent[x]) x = parent[x];
while (a != parent[a]) {
int z = a;
a = parent[a];
parent[z] = x;
}
return x;
}
void toUnion(int x1, int x2) {
int r1 = find(x1), r2 = find(x2);
if (r1 != r2) parent[r1] = r2;
}
int main() {
int n, i, j, k, h, f, sum = 0;
int course[1001] = { 0 };
cin >> n;
parent.resize(n+1);
isRoot.resize(n+1);
for (i = 1; i <= n; i++) parent[i] = i;
for (i = 1; i <= n; i++) {
scanf("%d:", &k);
for (j = 0; j < k; j++) {
cin >> h;
if (course[h] == 0)
course[h] = i;
toUnion(i, find(course[h]));
}
}
for (i = 1; i <= n; i++) isRoot[find(i)]++;
for (i = 1; i <= n; i++) if (isRoot[i] != 0)sum++;
cout << sum << endl;
sort(isRoot.begin(), isRoot.end(), cmp1);
for (i = 0; i < sum; i++) cout << isRoot[i] << (i == sum-1 ? "" : " ");
return 0;
}