单源最短路径基础算法总结

image-20220602235607401

N:端点数 M:边数

1.Dijkstra

dist[1] = 0, dist[i] = +∞
for i ← 1 to n
	t ← 不在s中的距离最近的点
	s ← t
	用t更新其他点的距离

时间复杂度分析

dist[1] = 0, dist[i] = +∞
for i ← 1 to n
	t ← 不在s中的距离最近的点  O(n^2)
  s ← t  n次
  用t更新其他点的距离	m次

朴素版的时间复杂度是\(O(n^2)\)

dist[1] = 0, dist[i] = +∞
for i ← 1 to n
	t ← 不在s中的距离最近的点  O(1)
  s ← t  n次
  用t更新其他点的距离	m * log^n

堆优化版时间复杂度是\(mlog^n\)

Q:为什么处理不了负数

因为Dijkstra每轮都要确定一个端点的最终最短路径,而如果存在负权边,那路径可能是需要拐弯的

比如,有以下边,由A出发,求A -> C的最短路

A -> B: 4
A -> C: 5
B -> C: -1

Dijkstra求出结果必然是 A -> C: 5,而实际结果是 A -> B -> C: 3

Q: 为什么边权都是正数时,不存在此问题

边权都是正数时,所有端点的最短路都是对着走到路径的增多不断增大的,因此不存在绕路走反而更近的情况,因此不存在此问题

2.Bellman-Ford

BF算法执行k轮的含义: 经过不超过K条边到达其他点的最短距离

存储下所有边M
置所有点的距离为无穷,dis[1] = 0

- 每轮循环尝试所有边,看能否对dis数组进行更新
- 如果有N条边,那么理论上更新N - 1次就能得到所有

3.SPFA

在Bellman-Ford基础上改进,Bellman_Ford每轮尝试使用所有边进行更新,而SPFA只使用上一轮更新过的点进行向后更新。

4.求负权回路

方法一 Bellman-Ford

BF算法执行k次的意思是,经过不超过K条边,到达其他点的最短距离,因此理论上说,假设图有N个点,那么执行N - 1轮,dis存储的就是所有的点的最短路,如果此时dis在执行一轮,仍然可以更新,那么就必然存在

方法二 SPFA

在SPFA基础上,设置一个cnt数组,存储每个点被更新的次数,理论上任意一个点被更新次数最多就是N-1,如果更新次数≥N,那必然是存在负权回路

posted @ 2022-09-09 11:09  INnoVation-V2  阅读(209)  评论(0编辑  收藏  举报