PAT 1107 Social Clusters

根据每个人的爱好,有相同的爱好就是同一个社交网络中,求有几个社交网络,每个的人数从大到小输出。
这一题是集合的题目,一开始想到了并查集,但不知道如何把爱好和人关联起来,以为是其他办法,看了一下别人的讲解,果真用的是并查集。
建立爱好的数组,将这一爱好的人都放入,分别将每个爱好中的人合并到一个并查集中去。最后用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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值