zoukankan      html  css  js  c++  java
  • prim算法求最小生成树

    prim算法求最小生成树

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    const int N = 501, INF = 0x3f3f3f3f;
    int d[N], g[N][N];
    int n, m;
    bool st[N];
    
    int prim()
    {
        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;
            
            if(i && d[t] == INF) return INF;
            if(i) res += d[t];
            st[t] = true;
            for(int j = 1;j <= n;j++)
                d[j] = min(d[j], g[t][j]);//注意这里与Dijkstra区别d[t] + d[t][j]
            
        }
        return res;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        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;
    }

    prime算法和Dijkstra算法求最小距离非常相似。

    一开始d[i]全都被赋值为+oo

    要找n个点,那么就要循环n次

    for  i  0 - n

    找到集合外距离最近的点,用新的距离最近的点t来更新其他点到集合的最短距离(Dijkstra这里是更新到起点的距离),st[t] = true;加入到集合当中来。

    必须要先累加再更新,如果有负权自环的话,就会再次更新自己 从而加入进来,先累加再更新下一次判断的话因为st[j] = true就不会再更新了。

    模拟一遍:i = 0, t = 1, d[1] = oo, 但是不会加入最小生成树的res里面来,因为只有i>0 时,res += d[t]。d[2] = 1, d[3] = 2, d[4] = 3。

    接着会用连接的最小距离2来更新其他点。注意是到集合的距离,所以也只是min(d[t], g[t][j]), 而Dijkstra是min(d[t], d[t] + g[t][j]);

  • 相关阅读:
    前端安全之XSS攻击
    从JavaScript执行上下文理解变量提升
    em、rem和px的区别
    纯CSS实现幻灯片效果
    小白在使用ISE编写verilog代码综合时犯得错误及我自己的解决办法
    结构体指针中的一点困惑
    xilinx fpga中块ram的使用——简单双端口ram的使用
    在模块中如何去写输出标志位的程序
    学习感悟
    xilinx fpga 生成3*3窗口
  • 原文地址:https://www.cnblogs.com/longxue1991/p/12714194.html
Copyright © 2011-2022 走看看