最小生成树

\(kruskal\) 算法

struct Kruskal{
    struct node{
        int u, v;
        i64 w;
        bool operator<(const node &t) const {
            return w < t.w;
        }
    };
    int n, m, cnt;
    i64 ans;
    vector<node> edg;
    Dsu dsu;
    Kruskal(int n_, int m_) : edg(m_ + 1) {
        cnt = 0;
        ans = 0;
        n = n_;
        m = m_;
        dsu = Dsu(n_);
        init();
    }

    inline void init() {
        for (int i = 1, u, v; i <= m; i++) {
            i64 w;
            std::cin >> u >> v >> w;
            edg[cnt++] = {u, v, w};
        }
        sort(edg.begin(), edg.begin() + cnt);
    }

    inline void get_tree() {
        int tot = 0;
        for (int i = 0; i < cnt; i++) {
            auto [u, v, w] = edg[i];
            if (dsu.mergy(u, v)) {
                tot++;
                ans += w;
            }
        }
        if (tot != n - 1) {
            return false;
        } else {
            return true;
        }
    }
};

void solve() {
    int n, m;
    std::cin >> n >> m;
    Kruskal ans(n, m);
    ans.get_tree();
}

\(prim\) 算法:

struct prim{
    struct node{
        int to, nxt;
        i64 w;
        node() {}
        node(int to, int nxt, i64 w = 1) : to(to), nxt(nxt), w(w) {}
    };
    struct S{
        int u;
        i64 dis;
        bool operator<(const S& t) const {
            return dis > t.dis;
        }
    };
    int n, m, cnt, tot;
    i64 ans;
    vector<node> edg;
    vector<int> head, vis;
    vector<i64> dist;
    prim(int n_, int m_) : edg(m_ << 1 | 1), head(n_ + 1), dist(n_ + 1, MOF), vis(n_ + 1) {
        cnt = 0;
        tot = 0;
        ans = 0;
        n = n_;
        m = m_;
        init();
    }

    inline void add(int u, int v, i64 w = 1) {
        cnt++;
        edg[cnt].to = v;
        edg[cnt].nxt = head[u];
        edg[cnt].w = w;
        head[u] = cnt;
    }

    inline void init() {
        for (int i = 1, u, v; i <= m; i++) {
            i64 w = 1;
            std::cin >> u >> v >> w;
            add(u, v, w);
            add(v, u, w);
        }
    }

    inline void Prim() {
        priority_queue<S> q;
        q.push((S){1, 0});
        dist[1] = 0;
        // vis[1] = 1;
        while (!q.empty()) {
            if (tot >= n) {
                break;
            }
            auto [u, dis] = q.top();
            q.pop();
            if (vis[u]) {
                continue;
            }
            vis[u] = 1;
            tot++;
            ans += dis;
            for (int i = head[u]; i; i = edg[i].nxt) {
                i64 v = edg[i].to;
                i64 w = edg[i].w;
                if (w < dist[v]) {
                    // vis[v] = 1;
                    dist[v] = w;
                    q.push((S){v, w});
                }
            }
        }
        if (tot == n) {
            cout << ans << '\n';
        } else {
            cout << "orz\n";
        }
    }
};

void solve() {
    int n, m;
    std::cin >> n >> m;
    prim ans(n, m);
    ans.Prim();
}
posted @ 2024-08-29 18:11  grape_king  阅读(23)  评论(0)    收藏  举报