0
点赞
收藏
分享

微信扫一扫

天梯 畅通工程之局部最小花费问题

炽凤亮尧 2022-04-14 阅读 30

天梯 畅通工程之局部最小花费问题

思路

kruskal算法求最小生成树。

因为如果已经有道路的话,那么这两个点算在一个集合中。剩下的,就求最小生成树就可以了。

代码

#include <bits/stdc++.h>
using namespace std;

#define all(x) std::begin(x), std::end(x)

struct edge {
    int u, v, w;
    edge(int u = 0, int v = 0, int w = 0) : u(u), v(v), w(w) {}
};

class DST {
    private:
        std::vector<int> dad;
        int cnt;
    public:
        DST(int size) {
            dad.assign(size + 1, -1);
            cnt = size;
        }
        void init(int size) {
            dad.assign(size + 1, -1);
            cnt = size;
        }
        int& operator [] (int i) {
            return dad[i];
        }
        int Find(int now) {
            if (dad[now] > 0)
                return dad[now] = Find(dad[now]);
            return now;
        }
        bool Union(int a, int b) {
            a = Find(a); b = Find(b);
            if (a == b)
                return false;
            dad[a] += dad[b];
            dad[b] = a;
            cnt --;
            return true;
        }
        const int count() const {
            return cnt;
        }
};

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int n;
    cin >> n;

    DST dst(n + 1);
    vector<edge> ed;
    int ans = 0;
    for (int i = 0; i < (n - 1) * n / 2; ++ i) {
        int u, v, w, d;
        cin >> u >> v >> w >> d;

        if (d == 1) {
            dst.Union(u, v);
        } else {
            ed.push_back({u, v, w});
        }
    }

    sort(ed.begin(), ed.end(), [](const edge &a, const edge &b) {
        return a.w < b.w;
    });

    for (auto &[u, v, w] : ed) {
        if (dst.Union(u, v)) {
            ans += w;
        }
    }

    cout << ans << '\n';
    
    return 0;
}
举报

相关推荐

0 条评论