• 最小生成树


    最小生成树

    Prim

    朴素版(O(n^2))和堆优化版(O(mlogn))

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    
    const int N = 510, INF = 0x3f3f3f3f;
    int n, m;
    int g[N][N], dist[N];
    bool st[N];
    
    int prim() {
        int res = 0;
        memset(dist, 0x3f, sizeof dist);
        for (int i = 0; i < n; ++i) {
            int t = -1;
            for (int j = 1; j <= n; ++j) {
                if (!st[j] && (t == -1 || dist[t] > dist[j])) t = j;
            }
            if (i && dist[t] == INF) return INF;
            if (i) res += dist[t];
            st[t] = true;
            for (int j = 1; j <= n; ++j) dist[j] = min(dist[j], g[t][j]);
        } 
        return res;
    }
    
    int main() {
        cin >> n >> m;
        memset(g, 0x3f, sizeof g);
        while (m--) {
            int a, b, c;
            cin >> a >> b >> c;
            g[a][b] = g[b][a] = min(g[a][b], c);
        }
        int t = prim();
        if (t == INF) puts("impossible");
        else cout << t << endl;
        
        return 0;
    }
    

    Kruskal

    (O(mlogn))

    • 将所有边按权重从小到大排序;
    • 枚举每条边a、b、w,如果a、b不连通,将这条边加入集合。
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    
    const int N = 200010;
    int n, m;
    int p[N];
    
    int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
    
    struct edge {
        int a, b, w;
        
        bool operator< (const edge &W) const {
            return w < W.w;
        }
    } edges[N];
    
    int main() {
        cin >> n >> m;
        for (int i = 0; i < m; ++i) {
            int a, b, w;
            cin >> a >> b >> w;
            edges[i] = {a, b, w};
        }
        
        sort(edges, edges + m);
        
        for (int i = 1; i <= n; ++i) p[i] = i;
        
        int res = 0, cnt = 0;
        for (int i = 0; i < m; ++i) {
            int a = edges[i].a, b = edges[i].b, w = edges[i].w;
            a = find(a), b = find(b);
            
            if (a != b) {
                p[a] = b;
                res += w;
                cnt++;
            }
        }
        
        if (cnt < n - 1) puts("impossible");
        else cout << res << endl;
        return 0;
    }
    
  • 相关阅读:
    mysql数据库中的锁
    HihoCoder
    旅游规划(双权连通图)
    单调栈的原理
    战争联盟(并查集)
    点赞狂魔(巧用STL容器事半功倍)
    这是二叉搜索树吗?
    好像是两种权的dijkstra
    pat--046.整除光棍(除法模拟)
    幸运数字 2
  • 原文地址:https://www.cnblogs.com/clown9804/p/12541616.html
Copyright © 2020-2023  润新知