PAT Advanced 1107 Social Clusters (30) [并查集]
Posted houzm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT Advanced 1107 Social Clusters (30) [并查集]相关的知识,希望对你有一定的参考价值。
题目
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个人,每个人都有自己喜欢的活动,有共同喜欢的活动的人组成集群,求集群数和每个集群中的组员个数
解题思路
辅助数组
用int act[n]数组记录各活动任意一个喜欢的人,在并查集之外的辅助数组,某个活动第一次被喜欢时,将喜欢此活动的人作为其元素值
并查集的使用
输入编号为i的A喜欢的活动时,寻找此活动的任意喜欢的人act[i](设其为B),将A、B合并到一个集群
统计操作
统计根节点总数即为集群总数,并在此过程中记录每个集群中的组员数
Code
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
const int maxn=1010;
int father[maxn],act[maxn],clst[maxn];
/* 并查集 - 初始化*/
void init(int n) {
for(int i=1; i<=n; i++) {
father[i]=i;
}
}
/* 并查集-查 */
int find(int x) {
int a=x;
while(x!=father[x])
x=father[x];
while(a!=father[a]) {
int temp=father[a];
father[a]=x;
a=temp;
}
return x;
}
/* 并查集-并 */
void Union(int a, int b) {
int af=find(a);
int bf=find(b);
if(af!=bf)
father[af]=bf;
}
bool cmp(int a, int b){
return a>b;
}
int main(int argc,char * argv[]) {
int n,t,h;
scanf("%d",&n);
init(n);
for(int i=1; i<=n; i++) {
scanf("%d:", &t);
for(int j=0; j<t; j++) {
scanf("%d", &h);
if(act[h]==0){
act[h]=i; //h习惯 第一次有人拥有
}
Union(i, act[h]); //将i合并到所属集群中
}
}
// 统计集群数,及集群中成员个数
set<int> cids;
for(int i=1;i<=n;i++){
clst[find(i)]++;
cids.insert(father[i]);
}
int ans=cids.size();
printf("%d
",ans);
sort(clst+1,clst+n+1, cmp); //从大到小
for(int i=1;i<=ans;i++){
printf("%d",clst[i]);
if(i<ans)printf(" ");
}
return 0;
}
以上是关于PAT Advanced 1107 Social Clusters (30) [并查集]的主要内容,如果未能解决你的问题,请参考以下文章
PAT-1107 Social Clusters (30 分) 并查集模板