zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    QSettings读写注册表、配置文件
    QSettings介绍
    桥接模式
    Qt之启动外部程序
    StringJDBC更改数据库的两种方式
    写代码注意事项
    maven仓库
    java关闭流,解压缩后的清除
    Java删除文件夹和文件
    浏览器禁用后退
  • 原文地址:https://www.cnblogs.com/Kanoon/p/12510372.html
Copyright © 2011-2022 走看看