单源最短路径Dijkstra算法的思想详细步骤代码
Posted 地球太危险了
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单源最短路径Dijkstra算法的思想详细步骤代码相关的知识,希望对你有一定的参考价值。
目录
一、算法思想
1、Dijkstra 算法是用来求解单源最短路径问题的经典算法,其本质上是一个贪心算法。
(PS: 求任意两个结点之间最短路径的有 Floyd 算法)
2、算法的基本思想是:设置一个顶点集合 S 并不断地做贪心选择来扩充这个集合。
3、该算法适用:1)边权为正,2)有向无向都适用。
有一些相关的性质:
- 对于边权为正的图,任意两个结点之间的最短路,不会经过重复的结点。
- 对于边权为正的图,任意两个结点之间的最短路,不会经过重复的边。
- 对于边权为正的图,任意两个结点之间的最短路,任意一条的结点数不会超过 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算法的思想详细步骤代码的主要内容,如果未能解决你的问题,请参考以下文章
[C++]单源最短路径:迪杰斯特拉(Dijkstra)算法(贪心算法)