其他分享
首页 > 其他分享> > 团伙头目

团伙头目

作者:互联网

https://www.acwing.com/problem/content/1520/

思路:
先找到在一个团伙中的人(可以用树的dfs来做,也可以用并查集来做),然后遍历每一个合法的集合,找到里面的头目。

并查集的做法

#include <iostream>
#include <unordered_map>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 3010;

int col[N],num[N],sum[N],con[N],n,k;
unordered_map<string,int> map;
string re_map[N];
bool st[N];

int find(int a){
    if(col[a] != a) col[a] = find(col[a]);
    return col[a];
}

int main(){
    cin >> n >> k;

    int cnt = 0,nums = 0;

    for(int i = 0; i < N; i++) col[i] = i, num[i] = 1;
    for(int i = 0; i < n; i++){
        string s1,s2;
        int val;

        cin >> s1 >> s2 >> val;
        if(!map.count(s1)) map[s1] = cnt,re_map[cnt] = s1,cnt ++;
        if(!map.count(s2)) map[s2] = cnt,re_map[cnt] = s2,cnt ++;

        int u = map[s1],v = map[s2];
        con[u] += val,con[v] += val;

        int f1 = find(u), f2 = find(v);
        if(f1 != f2){
            col[f1] = f2;
            num[f2] += num[f1];
            sum[f2] += val + sum[f1];
            nums ++;
        }else{
            //num[f2] += num[f1];
           sum[f2] += val;
        }
    }
    nums = cnt - nums;
    vector<pair<string,int>> out;

    for(int i = 0; i < cnt; i++){
        int u = find(i);

        if(st[u]) continue;
        if(num[u] < 3 || sum[u] <= k) nums--;
        else{
            int j = 0,idx = 0,val = -1;
            for(j = 0; j < cnt; j++){
                if(find(j) == u){
                    if(con[j] > val) val = con[j], idx = j;
                }
            }
            out.push_back({re_map[idx],num[u]});
        }

        st[u] = true;
    }

    sort(out.begin(),out.end());
    cout << nums << endl;
    for(auto v : out) cout << v.first << ' ' << v.second << endl;
    return 0;
}

图论的做法

#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>

using namespace std;

int n, k;
unordered_map<string, vector<pair<string, int>>> g;
unordered_map<string, int> total;
unordered_map<string, bool> st;

int dfs(string ver, vector<string> &nodes)
{
    st[ver] = true;
    nodes.push_back(ver);

    int sum = 0;
    for (auto edge : g[ver])
    {
        sum += edge.second;
        string cur = edge.first;
        if (!st[cur]) sum += dfs(cur, nodes);
    }

    return sum;
}

int main()
{
    cin >> n >> k;
    while (n -- )
    {
        string a, b;
        int t;
        cin >> a >> b >> t;
        g[a].push_back({b, t});
        g[b].push_back({a, t});
        total[a] += t;
        total[b] += t;
    }

    vector<pair<string, int>> res;
    for (auto item : total)
    {
        string ver = item.first;
        vector<string> nodes;
        int sum = dfs(ver, nodes) / 2;

        if (nodes.size() > 2 && sum > k)
        {
            string boss = nodes[0];
            for (string node : nodes)
                if (total[boss] < total[node])
                    boss = node;
            res.push_back({boss, (int)nodes.size()});
        }
    }

    sort(res.begin(), res.end());

    cout << res.size() << endl;
    for (auto item : res) cout << item.first << ' ' << item.second << endl;

    return 0;
}

标签:map,cnt,int,sum,头目,nodes,include,团伙
来源: https://www.cnblogs.com/xjtfate/p/16610678.html