let menu = ["Home", "Algorithms", "CodeHub", "VNOI Statistics"];

Overview

QBMST - Cây khung nhỏ nhất

solution.md

Bài này cần cài đặt thuật toán tìm cây khung nhỏ nhất. Có thể sử dụng Prim hoặc Kruskal đều được. Xem các bài viết sau để biết thêm chi tiết:

kruskal.cpp
Open in Github Download
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct DisjointSet {
    vector<int> cha, rank;
    DisjointSet(int n): cha(n + 1), rank(n + 1, 0) {
        for (int i=1; i<=n; i++) cha[i] = i;
    }
    int find(int u) {
        if (cha[u] != u) cha[u] = find(cha[u]);
        return cha[u];
    }
    bool join(int u, int v) {
        u = find(u);
        v = find(v);
        if (u == v) return false;
        if (rank[u] == rank[v]) rank[u]++;
        if (rank[u] > rank[v]) cha[v] = u;
        else cha[u] = v;
        return true;
    }
};

struct Edge { int u, v, w; };
bool operator < (const Edge &a, const Edge &b) {
    return a.w < b.w;
}

int main() {
    ios::sync_with_stdio(false); cin.tie(0);

    int n, m; cin >> n >> m;
    vector<Edge> e(m);
    for (Edge &e: e) cin >> e.u >> e.v >> e.w;

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

    DisjointSet set(n);
    int result = 0;
    for (Edge &e: e) {
        if (set.join(e.u, e.v)) result += e.w;
    }

    cout << result;
    return 0;
}
prim.cpp
Open in Github Download
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

struct Edge { int u, w; };
bool operator > (const Edge &a, const Edge &b) {
    return a.w > b.w;
}
typedef vector<vector<Edge>> Graph;
typedef priority_queue<Edge, vector<Edge>, greater<Edge>> MinHeap;

int prim (const Graph &g) {
    MinHeap heap;
    heap.push({1, 0});
    int result = 0;
    vector<bool> b(g.size(), false);
    while (!heap.empty()) {
        while (!heap.empty() && b[heap.top().u]) heap.pop();
        if (heap.empty()) break;
        Edge e = heap.top(); heap.pop();
        b[e.u] = true;
        result += e.w;
        for (Edge e: g[e.u]) heap.push(e);
    }
    return result;
}

int main() {
    ios::sync_with_stdio(false); cin.tie(0);

    int n, m; cin >> n >> m;

    Graph g(n+1);
    while (m--) {
        int u, v, w;
        cin >> u >> v >> w;
        g[u].push_back({v, w});
        g[v].push_back({u, w});
    }

    cout << prim(g);
    return 0;
}
Comments