PAT A1107 Social Clusters (30 分)——并查集

时间:2023-03-09 20:23:34
PAT A1107 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:

K​i​​: h​i​​[1] h​i​​[2] ... h​i​​[K​i​​]

where K​i​​ (>0) is the number of hobbies, and h​i​​[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
 #include <stdio.h>
#include <algorithm>
#include <set>
#include <string.h>
#include <vector>
#include <math.h>
#include <queue>
using namespace std;
const int maxn = ;
int n;
int father[maxn]={};
int peo[maxn][maxn];
set<int> hob;
set<int> fah;
int res[maxn]={};
bool cmp(int a,int b){
return a>b;
}
void init(){
for(int i=;i<=maxn;i++){
father[i]=i;
}
}
int findfather(int x){
int a=x;
while(x!=father[x]){
x=father[x];
}
while(a!=father[a]){
int z=a;
a=father[a];
father[z]=x;
}
return x;
}
void uni(int a,int b){
int fa=findfather(a);
int fb = findfather(b);
if(fa!=fb){
father[fb]=fa;
}
}
int main(){
init();
scanf("%d",&n);
for(int i=;i<=n;i++){
int k,fi;
scanf("%d: %d",&k,&fi);
peo[i][]=fi;
hob.insert(fi);
for(int j=;j<k;j++){
int x;
scanf("%d",&x);
peo[i][j]=x;
hob.insert(x);
uni(fi,x);
}
}
for(auto it:hob){
fah.insert(findfather(it));
//printf("%d %d\n",it,findfather(it));
}
printf("%d\n",fah.size());
for(int i=;i<=n;i++){
res[findfather(peo[i][])]++;
//printf("%d %d\n",findfather(peo[i][0]),res[findfather(peo[i][0])]);
}
sort(res,res+maxn,cmp);
for(int i=;i<fah.size();i++){
printf("%d",res[i]);
if(i<fah.size()-)printf(" ");
}
}

注意点:标准并查集,我是根据喜好来把人集合起来的,变量有点多,有点麻烦。看了大佬的代码,发现好像所有并查集的题目都是可以套模板的,他们是合并人,标记爱好,然后遍历isroot来得到集合个数