zoukankan      html  css  js  c++  java
  • dijkstra算法

    /*********************
    
    问题:
    给定一个有向图G=(V,E)和源点s,求s到G中其它每个顶点的最短路径。
    
    Dijkstra算法的具体实现方法:
    (1)设置两个顶点的集合S和T
    S中存放已经找到到源点s最短路径的顶点,初始时集合S中只有一个
    顶点,即源点s。
    T中存放当前还没有找到最短路径的顶点,即T=V-S。
    (2)在集合T中选取当前长度最短的一条路径(s,...,v),将v加入到
    集合S中,并修改源点s到集合T中每个顶点的最短路径长度;重复这一
    步骤,直到所有的顶点都加入到集合S中(即S=V,T=空),算法就结束了。
    
    
    Dijkstra算法的邻接矩阵实现,复杂度为O(V2)。
    
    *********************/
    
    #include<iostream>
    //#include<climits>
    //#include<string>
    //#include<cstdlib>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    
    const int N=5;  //最大顶点个数
    const int M=10; //最大边数
    const int inf=60000;  //表示无穷大
    int a[N+1][N+1];  //邻接矩阵
    int d[N+1];  //记录源点s到顶点u的距离
    int pre[N+1];  //记录源点s到顶点u的最短路径上u的前驱
    bool vis[N+1]; //表示顶点u是否已经加入集合S中了
    
    void dijkstra(int s){  //求源点s到其它顶点的最短路径
        //初始化
        for(int i=1; i<=N; ++i){
            d[i] = inf;  //把d[i]初始化为无穷大
            pre[i] = -1;  //每个顶点的父节点初始化为空
        }
        d[s] = 0;//s为源点
        memset(vis, false, sizeof(vis));  //所有点都不在集合S中
    
        //循环N次,以便于把每个点都加入集合S中
        for(int i=1; i<=N; ++i){
            int tmp = inf;
            int k = 0;
            //找出d值最小的点k
            for(int j=1; j<=N; ++j){
                if(!vis[j] && d[j]<tmp){
                    tmp = d[j];
                    k = j;
                }
            }
            if(k==0) return; //没有点可以加入集合S中了,剩余点不可达
            vis[k] = true;  //把点k加入集合S
    
            //更新k的邻居(不在集合S的)的d值
            for(int j=1; j<=N; ++j){
                if(!vis[j] && d[j]>d[k]+a[k][j]){
                    d[j] = d[k]+a[k][j];
                    pre[j] = k;
                }
            }
        }
    }
    
    void print_path(int s, int v){
        if(v==s){
            printf("%d", s);
        }
        else{
            if(pre[v] == -1)
                printf("path no exist!
    ");
            else{
                print_path(s, pre[v]);
                printf("->%d", v);
            }
        }
    }
    
    int main()
    {
        freopen("shortpath.in", "r", stdin);
        int u, v, w;  //边(u, v)和权值w
        for( int i=1; i<=N; ++i)  //初始化邻接矩阵
            for( int j=1; j<=N; ++j){
                if(i==j) a[i][j] = 0;
                else a[i][j] = inf;
            }
        for(int i=1; i<=M; ++i){
            cin>>u>>v>>w;
            a[u][v] = w;
            a[v][u] = w;
        }
    
        int s=1; //选择的一个源点
        dijkstra(s);  //求源点s到其它顶点的最短路径
        for(int v=1; v<=N; ++v){
            if(v==s) continue;
            printf("%d	", d[v] );  //打印s到顶点v的最短路径长度
            print_path(s, v);  //打印出源点s到v的路径
            printf("
    ");
        }
        return 0;
    
    }
    

  • 相关阅读:
    22 组合电路中的竞争--冒险
    21 典型的组合电路模块(2)
    vhdl和verilog的区别
    17 TTL电路系列(2)
    树莓派Pico
    ESP8266/ESP32自动下载电路原理分析
    CH340芯片
    26. 删除排序数组中的重复项
    25. K 个一组翻转链表
    23. 合并K个排序链表
  • 原文地址:https://www.cnblogs.com/Tovi/p/6194858.html
Copyright © 2011-2022 走看看