• GPTL L3-003 社交集群(并查集)


    数据有些弱,Union函数不判不等也可以过。

    题意:

    依次给出 n 个人的兴趣,不同人兴趣相交、不同兴趣所属人员相交均属于同一集群,求形成的不相交集群个数及每个集群的人数。

    思路:

    枚举每个兴趣的人员,以序号最小者作为集群代表与其他成员合并,追加 cnt 数组记录每个集群的人数。

    如题目输入:

    1 2 3 4 5 6 7 8 9 10
    7 1 3 2 3 7 1 7   1
        5 4 7   3      
          6            
          8            

    则存在 ( 2, 4, 6, 8 )、( 3, 5, 7 )、( 1 )三个集群。

    Tips:

    注意读入输入中的 ':'。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int M=1100;
    
    int fri[M],cnt[M];
    vector<int> like[M];
    
    int Find(int x){
        int f=x;
        while(f!=fri[f]) f=fri[f];
        int a=x,b;
        while(a!=fri[a]) b=fri[a],fri[a]=f,a=b; 
        return f;
    }
    
    void Union(int A,int B){
        int friA=Find(A);
        int friB=Find(B);
        if(friA!=friB)
            fri[friB]=friA,cnt[friA]+=cnt[friB];//friA一定小于friB
    }
    
    int main()
    {
        for(int i=0;i<M;i++) fri[i]=i,cnt[i]=1;
        int n;cin>>n;
        for(int i=1;i<=n;i++){
            int k;char c;cin>>k>>c;
            for(int j=0;j<k;j++){
                int t;cin>>t;
                like[t].push_back(i);
            }
        }
        for(int i=0;i<M;i++){
            if(like[i].size()>=2){
                for(int j=1;j<like[i].size();j++){
                    Union(like[i][0],like[i][j]);
                }
            }
        }
        vector<int> ans;
        for(int i=1;i<=n;i++)
            if(fri[i]==i) ans.push_back(cnt[i]);
        sort(ans.begin(),ans.end(),greater<int>());
        cout<<ans.size()<<endl;
        for(int i=0;i<ans.size();i++)
            cout<<(i?" ":"")<<ans[i];
        return 0;
    }
  • 相关阅读:
    MySQL之数据库优化
    cookie和session
    php自动加载
    php函数之strtr和str_replace的区别
    php函数之substr()
    阶段总结(一)
    json和xml
    sqlserver交换数据行中的指定列
    3 宏、条件编译
    5 常量与变量
  • 原文地址:https://www.cnblogs.com/Kanoon/p/12510372.html
Copyright © 2020-2023  润新知