Dijkstra
适用范围
单源点的最短路问题,时间复杂度为
O
(
n
∗
m
)
O(n*m)
O(n∗m)
在经过查找顺序优化的条件下,可以达到
O
(
m
l
o
g
n
)
O(mlogn)
O(mlogn),是最为高效的最短路算法
原理解释
- 准备工作
-
一个辅助数组
Dis[k]
记录从原点到各个顶点终点的最短路,也就是答案- D [ k ] = m i n ( < 源 点 到 D [ k ] 上 弧 的 权 值 > , < 源 点 到 D [ i ] 的 路 径 长 + D [ i ] 到 其 他 点 的 权 值 > ) D[k]=min(<源点到D[k]上弧的权值>,<源点到D[i]的路径长+D[i]到其他点的权值>) D[k]=min(<源点到D[k]上弧的权值>,<源点到D[i]的路径长+D[i]到其他点的权值>)
-
Path[k]
表示当前所求得的从源点到其余各顶点 V k V_k Vk的最短路- P a t h [ k ] = − 1 ( V 0 , V k 之 间 不 存 在 有 向 路 径 ) Path[k]=-1 (V_0,V_k之间不存在有向路径) Path[k]=−1(V0,Vk之间不存在有向路径)
- P a t h [ k ] = 当 前 最 短 路 径 上 V k 的 直 接 前 驱 节 点 序 号 ( V 0 , V k 之 间 不 存 在 有 向 路 径 ) Path[k]=当前最短路径上V_k的直接前驱节点序号 (V_0,V_k之间不存在有向路径) Path[k]=当前最短路径上Vk的直接前驱节点序号(V0,Vk之间不存在有向路径)
-
S[k]
记录 V 0 − > V k V_0->V_k V0−>Vk是否被确定了最短路 ->一个过滤器true
确定了最短路false
没有确定最短路
- 算法描述
- Initial
- 将源点
V
0
V_0
V0加入
S
中,即S[0]=true
- 将
V
0
V_0
V0到各个终点
V
i
V_i
Vi的最短路径长度初始化为权值,即
D[i]=G.arcs[0][i]
- PS:此处在写代码的时候是遍历所有边,如果无边,则初始化为
inf
- PS:此处在写代码的时候是遍历所有边,如果无边,则初始化为
- 如果
V
0
V_0
V0和
V
i
V_i
Vi之间有弧,则将
V
i
V_i
Vi的前驱置为
V
0
V_0
V0,即
Path[i]=0
,否则Path[i]=-1
- 将源点
V
0
V_0
V0加入
- Main
- 在所有从源点
V
0
V_0
V0出发的弧中选取一条权值最小的弧,这就是第一条最短路径,设这条最短路径的终点是
V
k
V_k
Vk,使得:
D [ k ] = M i n D [ i ] ∣ V i 在 集 合 V − S 中 D[k]=Min{D[i]|V_i在集合V-S中} D[k]=MinD[i]∣Vi在集合V−S中 - 把
V
k
V_k
Vk加入到
S
S
S中,
S[k]=true
- 更新从 V 0 V_0 V0出发到集合 V − S V-S V−S上任一顶点最短路径的长度,同时更改 V i V_i Vi的前驱为 V k V_k Vk。
- 若
D[k]+G.arcs[k][i]<D[i]
,则D[i]=D[k]+G.arcs[k][i]; Path[i]=k
- 重复上述步骤 n − 1 n-1 n−1次
- 在所有从源点
V
0
V_0
V0出发的弧中选取一条权值最小的弧,这就是第一条最短路径,设这条最短路径的终点是
V
k
V_k
Vk,使得: