1034 Head of a Gang(并查集)

1034 Head of a Gang

题意描述

由通话信息来判断几人是否位于一个帮派

输入输出格式

输入通话记录 输出 帮派的个数 以及每个帮派的头目和人数

数据规模

算法设计

这里采用并查集的做法。首先建立并查集数组unordered_map<string,string>ufs 再维护每个人的权重 unordered_map<string,gg>weight 最后 由于题目要求按头目字典序升序输出 故用 map<string,array<gg,2>>res 维护结果 头目 对应 人数 + 帮派的权值 值得注意的是 不能边读入边进行union 因为此时的结点权重信息是不完整的 而且 帮派的权重一定为帮派结点权重 / 2

c++11代码

#include <bits/stdc++.h>
using namespace std;
using gg = long long;
unordered_map<string,string>ufs;   //   并查集数组
unordered_map<string,gg>weight;    //   结点的权重
map<string,array<gg,2>>res;        //   结果 father 对应 人数 + 权重之和
string findFather(string x){
    return x == ufs[x] ? x : ufs[x] = findFather(ufs[x]);
}
void unionSets(string x, string y){
    auto a = findFather(x), b = findFather(y);
    if(a != b) weight[a] > weight[b] ? ufs[b] = a : ufs[a] = b;  
}
int main()
{
   ios::sync_with_stdio(false);
   cin.tie(0);
   gg n,k,time;
   string name1,name2;
   vector<array<string,2>>v;  
   cin>>n>>k;
   while(n--){
       cin>>name1>>name2>>time;
       if(not ufs.count(name1)) ufs[name1] = name1;
       if(not ufs.count(name2)) ufs[name2] = name2;
       weight[name1] += time;
       weight[name2] += time;
       v.push_back({name1,name2});   //   这里要注意 由于结点的权重不完整 不能在此处进行unionSets 
   }
   for(auto& i : v) unionSets(i[0],i[1]);
   for(auto& i : ufs){  //  统计 father 信息
       res[findFather(i.first)][1] += weight[i.first];
       res[findFather(i.first)][0]++;
   }
   for(auto i = res.begin();i != res.end();){   //   这里 整个帮派的权重和 一定等于 各个结点的权重和 / 2 
       if(i->second[1] / 2 <= k or i->second[0] <= 2) i = res.erase(i);
       else i++;
   }
   cout<<res.size()<<"\n";
   for(auto& i : res){
       cout<<i.first<<" "<<i.second[0]<<"\n";
   }
   return 0;
}

题目链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值