1107 Social Clusters (30point(s))
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
題目大意:
輸入 N 個人的愛好,若有兩個人有相同的愛好,則這兩個人視爲在同一社交圈,求所有人構成了多少社交圈數量,並輸出每個社交圈的人數,從大到小排序
設計思路:
並查集
- 社交圈是人組成的,愛好僅是判斷兩人是否在同一社交圈的媒介
- hobby[] 數組記錄當前愛好有無人喜歡
- 若還沒有,自己佔據此愛好,當作此社交圈的祖先
- 若有人,則把自己加入此社交圈
- 對每個人進行遍歷,記錄組成了多少社交圈,和每個社交圈的人數
編譯器:C (gcc)
include <stdio.h>
int cmp(const void *a, const void *b)
{
return *((int *)b) - *((int *)a);
}
int father[1010], rank[1010];
void makeset()
{
int i;
for (i = 0; i < 1010; i++) {
father[i] = i;
rank[i] = 0;
}
}
int getfather(int v)
{
if (father[v] == v)
return v;
father[v] = getfather(father[v]);
return father[v];
}
void judge(int x, int y)
{
int fx = getfather(x);
int fy = getfather(y);
if (rank[fx] > rank[fy]) {
father[fy] = fx;
} else {
father[fx] = fy;
if (rank[fx] == rank[fy])
rank[fy]++;
}
}
int main(void)
{
int n;
int hobby[1010] = {0}, result[1010] = {0};
int i, j, k, a;
makeset();
scanf("%d", &n);
for (i = 1; i <= n; i++) {
scanf("%d:", &k);
while (k--) {
scanf("%d", &a);
if (hobby[a] == 0)
hobby[a] = i;
else
judge(hobby[a], i);
}
}
for (i = 1; i <= n; i++)
result[getfather(i)]++;
qsort(result + 1, n, sizeof(result[0]), cmp);
for (i = 1; i <= n && result[i] > 0; i++)
;
printf("%d\n", i - 1);
for (j = 1; j < i; j++)
printf("%s%d", j > 1 ? " " : "", result[j]);
return 0;
}