zoukankan      html  css  js  c++  java
  • 【模板】最小生成树

    P3366 【模板】最小生成树

    //prim算法求最小生成树
    #include <iostream> #include <cstring> using namespace std; const int N = 5010, INF = 0x3f3f3f3f; int n, m, d[N], g[N][N]; bool st[N]; int prime() { memset(d, 0x3f, sizeof d); int res = 0; for(int i = 0; i < n; i ++) { int t = -1; for(int j = 1; j <= n; j ++) if(!st[j] && (t == -1 || d[t] > d[j])) t = j; st[t] = true; if(i){ if(d[t] == INF) return INF; res += d[t]; } for(int j = 1; j <= n; j ++) if(d[j] > g[t][j]) d[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 = prime(); if(t == INF) cout << "orz" << endl; else cout << t << endl; }

     Kruskal算法求最小生成树:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    using namespace std;
    const int N = 5010, M = 2e5 + 10;
    int n, m, p[N];
    struct Node{
        int a, b, w;
        bool operator < (const Node &t)const
        {
            return w < t.w;
        }
    }node[M];
    
    int find(int x)
    {
        if(x != p[x]) p[x] = find(p[x]);
        return p[x];
    }
    
    int main()
    {
        cin >> n >> m;
        for(int i = 0; i < m; i ++) p[i] = i;
    
        for(int i = 0; i < m; i ++)
        {
            int a, b, w;
            cin >> a >> b >> w;
            node[i] = {a, b, w};
        }
    
        sort(node, node + m);
        int res = 0, cnt = 0;
        for(int i = 0; i < m; i ++)
        {
            int a = node[i].a, b = node[i].b, w = node[i].w;
            int x = find(a), y = find(b);
            if(x != y)
            {
                p[x] = y;
                cnt ++;
                res += w;
            }
        }
    
        if(cnt < n - 1) puts("orz");
        else cout << res << endl;
    }

      可以看到,prime求最小生成树和dijkstra求最短路神奇的相似,不同之处在于生成树要把每条路径加进来,所以开始 i = 0时,d[t]为INF,不能加进来,每次贪心选择最小的边,然后向外扩展得到能扩展边的最小值等于d[j] = g[t][j],把它们都加到最小生成树里面res来。以点来进行扩展,所以复杂度是O(n^2)。

      而Kruskal算法则是枚举每条边,用贪心的方法从小到大把每条不在同一个连通块内的边(用并查集来判断)加进来,如果最后加进来的边的数目小于 n - 1,即没有把所有的点加进来,图不连通。

  • 相关阅读:
    monit安装配置
    php新加扩展模块
    centos6.5(64bit),python2.6.6安装MySQLdb模块
    esxi导出ovf模板注意事项
    gateone安装使用
    centos7上安装nagios及增加监控服务器
    zabbix自动发现主机并加入组绑定模板
    zabbix监控Windows-server
    zabbix设置中文并解决乱码问题
    centos7安装zabbix客户端并监控
  • 原文地址:https://www.cnblogs.com/longxue1991/p/13084419.html
Copyright © 2011-2022 走看看