zoukankan      html  css  js  c++  java
  • 洛谷P3366 【模板】最小生成树 题解 Prim+堆优化

    题目链接:https://www.luogu.com.cn/problem/P3366

    标准Prim((O(n^2+m)))代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 5050, maxm = 400040;
    struct Edge {
        int v, w, nxt;
        Edge() {};
        Edge(int _v, int _w, int _nxt) { v = _v; w = _w; nxt = _nxt; }
    } edge[maxm];
    int n, m, head[maxn], ecnt;
    void init() {
        ecnt = 0;
        memset(head, -1, sizeof(int)*(n+1));
    }
    void addedge(int u, int v, int w) {
        edge[ecnt] = Edge(v, w, head[u]); head[u] = ecnt ++;
        edge[ecnt] = Edge(u, w, head[v]); head[v] = ecnt ++;
    }
    int cost[maxn], ans;
    bool vis[maxn];
    void prim() {
        memset(cost, -1, sizeof(int)*(n+1));
        cost[1] = 0;
        for (int t = 0; t < n; t ++) {
            int u = -1;
            for (int i = 1; i <= n; i ++) {
                if (!vis[i] && cost[i] != -1 && (u == -1 || cost[u] > cost[i])) u = i;
            }
            ans += cost[u];
            vis[u] = true;
            for (int i = head[u]; i != -1; i = edge[i].nxt) {
                int v = edge[i].v, w = edge[i].w;
                if (cost[v] == -1 || cost[v] > w) cost[v] = w;
            }
        }
    }
    int main() {
        cin >> n >> m;
        init();
        while (m --) {
            int u, v, w;
            cin >> u >> v >> w;
            addedge(u, v, w);
        }
        prim();
        cout << ans << endl;
        return 0;
    }
    

    然后我寻思 Prim 和 Dijkstra 思想是一样的(不知道这么理解对不对囧~),所以可以采用 Dijkstra 一样的方法对 Prim 进行堆优化。

    Prim+优先队列((O(m cdot log m)))代码:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 5050, maxm = 400040;
    struct Edge {
        int v, w, nxt;
        Edge() {};
        Edge(int _v, int _w, int _nxt) { v = _v; w = _w; nxt = _nxt; }
    } edge[maxm];
    int n, m, head[maxn], ecnt;
    void init() {
        ecnt = 0;
        memset(head, -1, sizeof(int)*(n+1));
    }
    void addedge(int u, int v, int w) {
        edge[ecnt] = Edge(v, w, head[u]); head[u] = ecnt ++;
        edge[ecnt] = Edge(u, w, head[v]); head[v] = ecnt ++;
    }
    int cost[maxn], ans;
    bool vis[maxn];
    struct Node {
        int u, cost;
        Node() {};
        Node(int _u, int _cost) { u = _u; cost = _cost; }
        bool operator < (const Node x) const {
            return cost > x.cost;
        }
    };
    priority_queue<Node> que;
    void prim() {
        memset(cost, -1, sizeof(int)*(n+1));
        que.push(Node(1, 0));
        while (!que.empty()) {
            Node nd = que.top();
            que.pop();
            int u = nd.u;
            if (vis[u]) continue;
            vis[u] = true;
            ans += nd.cost;
            for (int i = head[u]; i != -1; i = edge[i].nxt) {
                int v = edge[i].v, w = edge[i].w;
                if (cost[v] == -1 || cost[v] > w) {
                    cost[v] = w;
                    que.push(Node(v, w));
                }
            }
        }
    }
    int main() {
        cin >> n >> m;
        init();
        while (m --) {
            int u, v, w;
            cin >> u >> v >> w;
            addedge(u, v, w);
        }
        prim();
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    jquery实现选项卡(两句即可实现)
    常用特效积累
    jquery学习笔记
    idong常用js总结
    织梦添加幻灯片的方法
    LeetCode "Copy List with Random Pointer"
    LeetCode "Remove Nth Node From End of List"
    LeetCode "Sqrt(x)"
    LeetCode "Construct Binary Tree from Inorder and Postorder Traversal"
    LeetCode "Construct Binary Tree from Preorder and Inorder Traversal"
  • 原文地址:https://www.cnblogs.com/quanjun/p/12927725.html
Copyright © 2011-2022 走看看