• 最小生成树


    最小生成树

    最小生成树(MST)是属于图论中的一种算法,主要用于解决最短路径,最小费用等问题
    目前有两种算法可以从一个加权图中找出最小生成树:
    首先是Prime算法,这种算法可以在加权图中找到一棵生成总费用(距离)最小的树
    即每个节点与父节点和子节点是最小(短)的。
    但这种算法每次需要遍历图中所有节点来确定父节点,然后遍历可用节点为子节点,故算法复杂度为O(V^2)

    还有一种算法为Dijkstra算法,它主要解决单源的最短路径(费用)等问题,
    因为每个节点中存储的是离给定节点的最小(最少)距离(费用)。

    这两种算法均不能解决负权值的图。
    下面是这两种算法的C++具体实现,造好轮子以备不时之需。

    代码

    #include <iostream>
    using namespace std;
    
    
    //WHITE代表节点未访问,GRAY代表节点正在访问,BLACK代表节点已经访问 
    const int WHITE = 0;
    const int GRAY = 1;
    const int BLACK = 2;
    
    //定义一个比所有权值都大的数,作为无穷大 
    const int INFTY = (1<<10);
    const int MAX = 25;
    int M[MAX][MAX];
    //N表示图的节点数目, s表示 dijkstra 算法中的起始点 
    int N, s;
    
    //primes算法 
    int prim(){
        //u为当前访问的父节点
        //d[i]表示第i个节点的所有边中,权值最小的边
        //p[i]表示MST中节点i的父节点 
        int mincost, u;
        int d[MAX], p[MAX], color[MAX];
        //初始化 
        for (int i=0; i<N; i++){
            d[i] = INFTY; p[i] = -1; color[i] = WHITE;
        }
        d[0] = 0;
        
        while (true){
            mincost = INFTY; u = -1;
            //搜索当前父节点 
            for (int i=0; i<N; i++){
                if (mincost>d[i] && color[i]!=BLACK){
                    u = i; mincost = d[i];
                }
            }
            if (u==-1) break;
            color[u] = BLACK;
            //对当前父节点搜索子节点,并更新权值 
            for (int v=0; v<N; v++){
                if (color[v]!=BLACK && M[u][v]!=INFTY){
                    if (d[v]>M[u][v]){
                        d[v] = M[u][v];
                        p[v] = u;
                        color[v] = GRAY;
                    }
                }
            }
        }
        
        int sum = 0;
        //打印MST总和 
        for (int i=0; i<N; i++){
            if (p[i]!=-1) sum+=M[i][p[i]];
        }
        return sum;
    } 
    
    void dijkstra(){
        int mincost;
        
        //与prim算法不同,d[i]表示起点s到i的最短路径 
        int d[MAX], color[MAX];
        
        for(int i=0; i<N; i++){
            d[i] = INFTY;
            color[i] = WHITE;
        }
        
        d[s-1] = 0;
        color[s-1] = GRAY;
        
        while (true){
            mincost = INFTY;
            int u = -1;
            for (int i=0; i<N; i++){
                if (mincost>d[i] && color[i] != BLACK){
                    u = i;
                    mincost = d[i];
                }
            }
            if (u==-1) break;
            color[u] = BLACK;
            for (int v=0; v<N; v++){
                if (color[v]!=BLACK && M[u][v]!=INFTY){
                    int dis = M[u][v] + d[u];
                    if (d[v]>dis){
                        d[v] = dis;
                        color[v] = GRAY;
                    }
    
                }
            }
            
        }
        //打印所有节点与起点s的联通情况,如果不连通打印-1,否则打印最短距离 
        for (int i=0; i<N; i++){
            cout<<i<<" "<<(d[i]==INFTY?-1:d[i])<<endl;
        }
        
        
    }
    
    int main(){
        cin>>N;
        
        for (int i=0; i<N; i++){
            for(int j=0; j<N; j++){
                M[i][j] = INFTY;
            }
        }
        //输入初始图G的邻接矩阵 
        /*    
        for (int i=0; i<N; i++){
            for(int j=0; j<N; j++){
                int x;
                cin>>x;
                M[i][j] = x;
            }
        }
        
        */
        cin>>s;
        
        cout<<prim()<<endl;
    
        dijkstra();
    
        return 0;
    }
    
  • 相关阅读:
    Linux 服务器注意事项
    维基逃离MySQL 力挺开源数据库 MariaDB
    服务器性能优化
    1 Nginx + 12 Tomcat +2DB 实现2个程序负载均衡
    服务器虚拟化技术 对比简介
    vSphere虚拟系统 添加虚拟服务器
    IIS停止服务 报错Connections_Refused
    windows服务器 IIS FTP服务
    tomcat solr服务无法搜索中文
    查看php相关信息
  • 原文地址:https://www.cnblogs.com/sakurapiggy/p/13021252.html
Copyright © 2020-2023  润新知