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. Asocial clusteris a set of people who have some of their hobbies in common. You are supposed to find all the clusters.算法
Each input file contains one test case. For each test case, the first line contains a positive integerN(≤1000), the total number of people in a social network. Hence the people are numbered from 1 toN. ThenNlines follow, each gives the hobby list of a person in the format:spa
Ki:hi[1]hi[2] ...hi[Ki]code
whereKi(>0) is the number of hobbies, andhi[j]is the index of thej-th hobby, which is an integer in [1, 1000].orm
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.排序
8 3: 2 7 10 1: 4 2: 5 3 1: 4 1: 3 1: 4 4: 6 8 1 5 1: 4
3 4 3 1
course[h]
记录喜欢活动h的人的编号,使用findFather(course[h])
查找这我的所在集合的根结点。最后合并,i
与 findFather(course[h])
合并。#include <cstdio> #include <algorithm> using namespace std; const int maxn = 1010; int father[maxn]; int isRoot[maxn]; int course[maxn]; int n; bool cmp(int a, int b) { return a > b; } void init(int n) { for (int i = 1; i <= n; i ++) father[i] = i; } int findFather(int x) { while (x != father[x]) { x = father[x]; } return x; } void Union(int a, int b) { int faA = findFather(a); int faB = findFather(b); if (faA != faB) father[faB] = faA; } int main() { //freopen("test.txt", "r", stdin); scanf("%d", &n); init(n); int k, h; for (int i = 1; i <= n; i ++) { scanf("%d:", &k); for (int j = 1; j <= k; j ++) { scanf("%d", &h); if (course[h] == 0) course[h] = i; Union(i, findFather(course[h])); } } for (int i = 1; i <= n; i ++) { isRoot[findFather(i)] ++; } int sum = 0; for (int i = 1; i <= n; i ++) { if (isRoot[i] != 0) sum ++; } sort(isRoot, isRoot + n + 1, cmp); //注意isRoot中包括下标n,所以排序的最后一个位置要加1 printf("%d\n", sum); for (int i = 0; i < sum; i ++) { printf("%d", isRoot[i]); if (i < sum - 1) printf(" "); } return 0; }
参考资料:《算法笔记》.