单源最短路径Dijkstra算法的思想详细步骤代码

Posted 地球太危险了

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单源最短路径Dijkstra算法的思想详细步骤代码相关的知识,希望对你有一定的参考价值。

目录

一、算法思想

二、算法详细步骤

三、伪代码 + C++代码

四、算法复杂度分析

五、算法改进

六、应用案例


一、算法思想

1、Dijkstra 算法是用来求解单源最短路径问题的经典算法,其本质上是一个贪心算法。

   (PS: 求任意两个结点之间最短路径的有 Floyd 算法)

2、算法的基本思想是:设置一个顶点集合 S 并不断地做贪心选择来扩充这个集合。

3、该算法适用:1)边权为,2)有向无向都适用

有一些相关的性质:

  1. 对于边权为正的图,任意两个结点之间的最短路,不会经过重复的结点。
  2. 对于边权为正的图,任意两个结点之间的最短路,不会经过重复的边。
  3. 对于边权为正的图,任意两个结点之间的最短路,任意一条的结点数不会超过 n ,边数不会超过 n - 1 。

 

二、算法详细步骤

假设:

        1)已知带权图 G = (V, E)

       - V: 顶点(Vertex)的集合

       - E: 边(Edge)的集合

                      - 边 e = (u, v), u  V, v  V

        2)一个顶点属于S当且仅当从源到该顶点的最短路径长度已知。

        3)  数据结构:数组d,为记录当前每个顶点所对应的最短特殊路径长度(源v0到该顶点)。

算法步骤:

1、S 中初始时仅包含源 v0

2、从顶点集合 V - S 中选取最短特殊路径长度最短的顶点,并将其加入 S

3、对数组 d 进行更新(更新条件:若源 v0 通过某个顶点到该顶点的路径比原先 d 数组保存的小)

 

三、伪代码 + C++代码

1、伪代码

清除所有点的标号  // 属于集合S的标记
设d[0] = 0, 其他d[i] = INF  // initial
循环n次 
    在所有未标号结点中,选出d值最小的结点x  // 从V - S中选出从源出发距离最短的顶点
    给结点x标记  // 加入集合S
    对于从x出发的所有边(x,y),更新d[y] = mind[y], d[y]+w(x, y)  // 更新所有x的出边顶点
 

 

2、C++代码实现

memset(v, 0, sizeof(v));
for(int i = 0; i < n; i++) d[i] = (i==0 ? 0 : INF);
for(int i = 0; i < n; i++) 
    int x, m = INF;
    for(int y = 0; y < n; y++) if(!v[y] && d[y]<=m) m = d[x=y];
    v[x] = 1;
    for(int y = 0; y < n; y++) d[y] = min(d[y], d[x] + w[x][y]);

 

四、算法复杂度分析

 

五、算法改进

 

六、应用案例

 

更新:2021年5月3日

未完,待续。。。

 

 

以上是关于单源最短路径Dijkstra算法的思想详细步骤代码的主要内容,如果未能解决你的问题,请参考以下文章

Dijkstra算法详细(单源最短路径算法)

贪心算法(Dijkstra)解决单源最短路径问题(C++)

[C++]单源最短路径:迪杰斯特拉(Dijkstra)算法(贪心算法)

算法入门之单源最短路径算法:Dijkstra(迪杰斯特拉)算法

单源最短路径---Dijkstra算法

图文解析 Dijkstra单源最短路径算法