根据每个人的爱好,有相同的爱好就是同一个社交网络中,求有几个社交网络,每个的人数从大到小输出。
这一题是集合的题目,一开始想到了并查集,但不知道如何把爱好和人关联起来,以为是其他办法,看了一下别人的讲解,果真用的是并查集。
建立爱好的数组,将这一爱好的人都放入,分别将每个爱好中的人合并到一个并查集中去。最后用set统计并查集的数量,再用一个数组统计每个并查集的人数,然后排序。
反思,对于并查集的理解不够,导致不能第一时间用并查集解出这一题。
(用时:1:08:30.81)
别人的讲解:https://blog.csdn.net/liuchuo/article/details/52191082
#include <bits/stdc++.h>
using namespace std;
int getFather(int x,int father[])
{
while(father[x]!=x) {
x=father[x];
}
return x;
}
void unionFather(int a,int b,int father[])
{
int fa = getFather(a,father);
int fb = getFather(b,father);
if(fa<fb) {
father[fb] = fa;
} else {
father[fa] = fb;
}
}
int main()
{
int n;
scanf("%d",&n);
vector<int> hobby[1001];
int father[n+1];
for(int i=1; i<=n; i++) {
father[i]=i;
}
int k;
int hb;
for(int i=0; i<n; i++) {
scanf("%d:",&k);
for(int j=0; j<k; j++) {
scanf("%d",&hb);
hobby[hb].push_back(i+1);
}
}
int hobSize;
for(int i=1; i<1001; i++) {
hobSize=hobby[i].size();
for(int j=0; j<hobSize; j++) {
if(j<hobSize-1) {
unionFather(hobby[i][j],hobby[i][j+1],father);
}
}
}
set<int> social;
int countP[n+1]= {0};
int fa=0;
for(int i=1; i<=n; i++) {
fa = getFather(i,father);
social.insert(fa);
countP[fa]++;
}
printf("%d\n",social.size());
int j=0;
for(int i=2; i<=n; i++) {
int t= countP[i];
for( j=i-1; j>=1&&t>countP[j]; j--) {
countP[j+1] = countP[j];
}
countP[j+1] = t;
}
for(int i=1; i<=n; i++) {
if(countP[i]==0) {
break;
}
if(i==1) {
printf("%d",countP[i]);
} else {
printf(" %d",countP[i]);
}
}
printf("\n");
return 0;
}