PAT甲题题解-1034. Head of a Gang (30)-并查集

给出n和k
接下来n行,每行给出a,b,c,表示a和b之间的关系度,表明他们属于同一个帮派
一个帮派由>2个人组成,且总关系度必须大于k。
帮派的头目为帮派里关系度最高的人。
(注意,这里关系度是看帮派里边的和,而不是帮派里所有个人的总和。
如果是按个人算的话,相当于一条边加了两次,所以应该是>2*k)
问你有多少个合格帮派,以及每个帮派里最大的头目是谁,按字典序输出

先并查集一下,然后统计每个帮的成员数、总关系度、以及头目

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <cmath>
#include <map>

using namespace std;
const int maxn=(1000+5)*2;
map<string,int> maps;
string id_name[maxn];
int rel[maxn]; //每个人的weight
int vis[maxn];
struct Gang{
    string name;
    int num;
    int tot=0;
    int maxweight=0;
    bool operator<(const Gang tmp)const{
        if(name.compare(tmp.name)<=0)
            return true;
        else
            return false;
    }
}gang[maxn];
//并查集
struct UF{
    int fa[maxn];
    int num[maxn];
    void init(){
        for(int i=0;i<maxn;i++){
            fa[i]=i;
            num[i]=1;
        }
    }
    int find_root(int u){
        if(fa[u]!=u)
            fa[u]=find_root(fa[u]);
        return fa[u];
    }
    void Union(int x,int y){
        int fx=find_root(x);
        int fy=find_root(y);
        if(fx!=fy){
            fa[fy]=fx;
            num[fx]+=num[fy];
        }
    }
}uf;

int main()
{
    char str1[20],str2[20];
    int a;
    int cnt=0;
    int n,k;
    uf.init();
    memset(rel,0,sizeof(rel));
    scanf("%d %d",&n,&k);
    for(int i=0;i<n;i++){
        cin>>str1>>str2;
        scanf("%d",&a);
        if(maps[str1]==0){
            maps[str1]=++cnt;
            id_name[cnt]=str1;
        }
        if(maps[str2]==0){
            maps[str2]=++cnt;
            id_name[cnt]=str2;
        }
        rel[maps[str1]]+=a;
        rel[maps[str2]]+=a;
        uf.Union(maps[str1],maps[str2]);
    }
    memset(vis,0,sizeof(vis));
    int gangcnt=0;
    //父亲一样的属于同一个组,建立父亲id与帮派之间的映射
    for(int i=1;i<=cnt;i++){
        int group=uf.find_root(i);
        if(!vis[group]){
            vis[group]=++gangcnt;
            gang[gangcnt].num=uf.num[group];
            gang[gangcnt].tot+=rel[i];
            gang[gangcnt].maxweight=rel[i];
            gang[gangcnt].name=id_name[i];
        }
        else{
            int id=vis[group];
            gang[id].tot+=rel[i];
            if(rel[i]>gang[id].maxweight){
                gang[id].name=id_name[i];
                gang[id].maxweight=rel[i];
            }
        }
    }
    sort(gang+1,gang+gangcnt+1);
    int ans=0;
    for(int i=1;i<=gangcnt;i++){
//tot要除以2,因为一条边的weight加了2次
        if(gang[i].num>2&&gang[i].tot/2>k){

            ans++;
        }
    }
    printf("%d
",ans);
    for(int i=1;i<=gangcnt;i++){
        if(gang[i].num>2&&gang[i].tot/2>k){
            cout<<gang[i].name<<" "<<gang[i].num<<endl;
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/chenxiwenruo/p/6735433.html