• PAT甲题题解-1107. Social Clusters (30)-PAT甲级真题(并查集)


      题意:有n个人,每个人有k个爱好,如果两个人有某个爱好相同,他们就处于同一个集合。问总共有多少个集合,以及每个集合有多少人,并按从大到小输出。

      很明显,采用并查集。vis[k]标记爱好k第一次出现的人的编号,如果为0则表示未出现。

      当前第i个人若也存在爱好k,则只要将i与vis[k]两个人合并即可。

          最后father[i]相同的即处在同一个集合中。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <string.h>
    #include <cmath>
    using namespace std;
    /*
    并查集
    */
    const int maxn=1005;
    int vis[maxn]; //vis[i]标记某爱好第一次出现在第几个人,0表示还未出现。
    int n;
    
    struct UF{
        int father[maxn];
        void init(){
            for(int i=0;i<maxn;i++){
                father[i]=i;
            }
        }
        int find_root(int x){
            if(father[x]!=x){
                father[x]=find_root(father[x]);
            }
            return father[x];
        }
        void Union(int x,int y){
            int fx=find_root(x);
            int fy=find_root(y);
            if(fx!=fy){
                father[fy]=fx;
            }
        }
    }uf;
    
    bool cmp(int a,int b){
        return a>b;
    }
    int main()
    {
        char str[20];
        int num,a;
        scanf("%d",&n);
        memset(vis,-1,sizeof(vis));
        uf.init();
        for(int i=1;i<=n;i++){
            scanf("%s",str);
            int len=strlen(str);
            str[len-1]='';
            num=atoi(str);
            for(int k=0;k<num;k++){
                scanf("%d",&a);
                if(vis[a]==-1)
                    vis[a]=i;
                else{
                    uf.Union(vis[a],i); //若已出现过,则第i个人与第vis[a]个人合并,即分为一组
                }
            }
        }
        int cnt[n+1];
        int res=0;
        memset(cnt,0,sizeof(cnt));
        for(int i=1;i<=n;i++){
            int idx=uf.find_root(i);
            if(cnt[idx]==0)
                res++;
            cnt[idx]++;
        }
        sort(cnt+1,cnt+n+1,cmp);
        printf("%d
    ",res);
        for(int i=1;i<res;i++)
            printf("%d ",cnt[i]);
        printf("%d",cnt[res]);
        return 0;
    }
    View Code
  • 相关阅读:
    GDB+QEMU调试内核模块(实践篇)
    排序算法的python实现
    Linux命令行相关
    操作系统与网络
    计算机组成原理
    有了自己的技术博客
    if 和 if else
    十效率换算成十六进制
    <<左移 >>右移 >>>无符号右移 &与运算 |或运算 ^异或运算 ~反码
    // &与 // |或 // ^异或 // !非 // &&短路 // ||短路
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/6119256.html
Copyright © 2020-2023  润新知