Conscription POJ - 3723 (最小生成树+并查集)

题目: 传送门
思路:
把人看成点,征募花费看作边,那么就有一个无向图,因为当x和y关系是d时,在已招募x的情况下招募y的花费是10000-d,最小化花费等价于最大化d,故就是求“最大支撑树”(有V个节点,V-1条边,且边权重和最大),进而把d保存为-d,就转换成求无向图的最小生成树问题,直接套模板解决,注意,最后要用10000*V(人数)-最小生成树的边权和
Code:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>

using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const int inf = 0x3f3f3f3f;
const int maxn = 100007;

struct node {
    
    
    int from, to, dist;
    bool operator < (const node& other) const {
    
    
        return dist > other.dist;
    }
};
int n, m, v, e;
priority_queue<node> q;
int fa[maxn];
int rk[maxn];

void init() {
    
    
    for (int i=0;i<=v;i++) {
    
    
        fa[i] = i;
        rk[i] = 0;
        while (!q.empty()) {
    
    
            q.pop();
        }
    }
}
int find_root(int x) {
    
    
    return x == fa[x] ? x : fa[x] = find_root(fa[x]);
}
void merge(int x, int y) {
    
    
    x = find_root(x);
    y = find_root(y);
    if (x == y)  return;
    if (rk[x] < rk[y]) {
    
    
        fa[x] = y;
    } else {
    
    
        fa[y] = x;
        if (rk[x] == rk[y])  rk[x]++;
    }
}
int main()
{
    
    
    int f, t, d;
    int T;
    scanf("%d", &T);
    while (T--) {
    
    
        scanf("%d %d %d", &n, &m, &e);
        v = n + m;
        init();

        for (int i=0;i<e;i++) {
    
    
            scanf("%d %d %d", &f, &t, &d);
            q.push(node {
    
    f, n+t, -d});
            q.push(node {
    
    n+t, f, -d});

        }
        int in_num = 0;
        ll ans = 10000*v;
        
        while (!q.empty()) {
    
    
            if (in_num == v-1)  break;
            node tp = q.top();q.pop();
            if (find_root(tp.from) != find_root(tp.to)) {
    
    
                ans += tp.dist;
                in_num++;
                merge(tp.from, tp.to);
            }
        }
        printf("%lld\n", ans);
    }
    

    return 0;
}

猜你喜欢

转载自blog.csdn.net/u010017231/article/details/108839362