Boruvka最小生成树模板

纵然是瞬间 提交于 2020-03-04 00:03:47
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e3 + 5;
const int maxm = 5e5 + 5;
namespace MST {
    struct edge {
        int u, v, w;
    }E[maxm];
    int n, m;
    int tot = 0;
    void addedge(int u, int v, int w) {
        E[++tot].u = u;
        E[tot].v = v;
        E[tot].w = w;
    }

    int fa[maxn];
    void init() {
        for (int i = 1; i <= n; i++) {
            fa[i] = i;
        }
    }
    int find(int x) {
        return x == fa[x] ? x : fa[x] = find(fa[x]);
    }
    int Union(int u, int v) {
        int fu = find(u), fv = find(v);
        fa[fu] = fv;
    }

    int better(int i, int j) {
        if (j == 0)return 1;
        if (E[i].w != E[j].w) {
            return E[i].w < E[j].w;
        }
        else return i < j;
    }

    int best[maxn];
    int used[maxm];

    int solve() {
        int sum = 0, merge = 0;
        bool isupdate = 1;
        while (isupdate) {
            isupdate = 0;
            memset(best, 0, sizeof best);

            for (int i = 1; i <= tot; i++) {//找到每个连通块的最短出边
                if (used[i])continue;
                int fu = find(E[i].u), fv = find(E[i].v);
                if (fu == fv)continue;

                if (better(i, best[fu]))best[fu] = i;
                if (better(i, best[fv]))best[fv] = i;
            }

            for (int u = 1; u <= n; u++) {
                if (best[u] && !used[best[u]]) {
                    isupdate = 1;
                    sum += E[best[u]].w;
                    merge++;
                    Union(E[best[u]].u, E[best[u]].v);
                    used[best[u]] = 1;
                }
            }
        }
        return merge == n - 1 ? sum : -1;
    }
}
using namespace MST;
int main() {
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        addedge(u, v, w);
    }
    init();
    int ans=solve();
    if (ans != -1) {
        cout << ans << endl;
    }
    else {
        cout << "orz\n";
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!