zoukankan      html  css  js  c++  java
  • Dijkstra算法(《算法笔记》)

    一、算法思想

    Dijkstra算法适用于单源最短路问题,即给定图G和起点s,通过算法得到从s到其他每个顶点的最短距离。
    基本思想:设置一个集合S,存放已经被访问过的点,每次从V-S(未被访问过的点)中选择与起点s距离最短的点(记为u),访问并加入集合S中。将u作为中介点,优化所有从s经过u到达v的最短距离。

    二、具体实现

    • 集合S(存放已经被访问过的点)用bool型数组 vis[]实现,vis中的元素初始化都为false,被访问过后变为true

    • 用int型数组表示从起点s到v的最短距离,初始化赋为一个很大的数INF(1000000000)

    • 图用邻接矩阵表示,int型的数组G[][],两个点不可达,则G[u][v]为INF,两个点可达,则为它们之间的距离
      伪代码实现:

    Dijkstra(G,dis[],s){
    	初始化;
    	for(循环n次){
    		u= 还未被访问中使dis[u]最小的点的下标;
    		访问u;
    		for(从u可以到达的所有顶点v){
    			if(v未被访问&&以u为中介点可以使dis[v]更小)
    				优化dis[v]
    		}
    	}
    }
    

    三、代码实现

    C++版本

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    
    const int MAXN=1000; //最大顶点数
    const int INF=1000000000;   //无穷大的距离值
    int n;  //顶点数
    int G[MAXN][MAXN];  //图的邻接矩阵
    bool vis[MAXN]={false};  //没访问过的顶点为false
    int dis[MAXN];
    
    void Dijkstra(int s){   //给定一个起点,计算到每个点距离的最小值
        fill(dis,dis+MAXN,INF); //将距离的每一个值赋值为INF
        dis[s]=0; //到自身的距离为0
        int u;  //未被访问的顶点的集合中与s距离最小的点
        int minv;   //最小距离
        for(int i=0;i<n;i++){   //每次选择一个未被访问的顶点中距离最小的点
            u=-1;
            minv=INF;
            for(int j=0;j<n;j++){
                if(vis[j]==false && dis[j]<minv){
                    u=j;
                    minv=dis[j];
                }
            }
            if(u==-1)   //剩下未被访问的顶点与s不连通
                return;
            else{
                vis[u]=true;    //访问u
                //如果v未被访问过,u可达v,已u为中介可以使dis[v]更优就更新dis[v]
                for(int v=0;v<n;v++){
                    if(vis[v]==false&&G[u][v]!=INF&&((dis[u]+G[u][v])<dis[v])){
                        dis[v]=dis[u]+G[u][v];  //更新dis[v]
                    }
                }
            }
        }
    }
    int main()
    {
        int u,v,w;
        int m,s;
        fill(G[0],G[0]+MAXN*MAXN,INF);
        printf("输入顶点数和边数和起点:");
        scanf("%d%d%d",&n,&m,&s);
        for(int i=0;i<m;i++){
            scanf("%d%d%d",&u,&v,&w);
            G[u][v]=w;
        }
        Dijkstra(s);
        for(int i=0;i<6;i++){
            printf("%d ",dis[i]);
        }
        return 0;
    }
    
    

    Python版本

    MAXN = 1000     # 最大顶点数
    INF = 1e9       # 无穷大的值
    G = [[INF]*MAXN for i in range(MAXN)]   # 图的邻接矩阵
    dis = [INF]*MAXN    # 每一个点与起点距离的最小值
    vis = [False]*MAXN  # 存放已经被访问过的点
    n=int(input())     # 输入顶点数
    
    def Dijkstra(s):
        dis[s] = 0
        for i in range(n):     # 循环n次
            minv = INF
            u = -1
            for j in range(n):  # 寻找与s距离最小的点,并且该点未被访问过
                if vis[j] == False and dis[j]<minv:
                    u = j
                    minv = dis[j]
            if u== -1:
                return
            else:
                vis[u] = True
                for v in range(n):  # 以u为中介点,优化从s经过u到达v的最短路径
                    if vis[v]==False and G[u][v]!=INF and dis[u] + G[u][v] < dis[v]:
                        dis[v] = dis[u] + G[u][v]
    
    

    四、题目

    有的题目会有多条达到最短距离的路径,就要看第二标尺,来确定最终选择哪条路径

    1. 给每条边增加一个边权,要求在最短路径上的边权之和最小
    2. 给每个点增加一个点权,要求在最短路径上的点权之和最大
    3. 问有多少条路径
    作者:inss!w!
    版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 相关阅读:
    python K-means工具包初解
    Struts2学习笔记1
    北邮iptv用WindowsMediaplayer打不开的解决的方法
    数据挖掘十大经典算法(9) 朴素贝叶斯分类器 Naive Bayes
    Java中Queue类实现
    LinkedList
    android 自定义 radiobutton 文字颜色随选中状态而改变
    Android自定义radiobutton(文字靠左,选框靠右)
    Android进阶2之APK方式换肤
    Android APK方式换肤实现原理
  • 原文地址:https://www.cnblogs.com/Hfolsvh/p/14747901.html
Copyright © 2011-2022 走看看