Dijkstra
WARNING:前方缝合怪
分析:最常见的三种最短路算法的情况
算法名称 时间复杂度(最好) 时间复杂度(最坏) 空间复杂度 主要用途
Dijkstra O(N^2) O(N^2) O(N) 单源
SPFA O(KM)(k为常数) O(NM) O(N) 单源
Floyd O(N^3) O(N^3) O(N^2) 多源
可以知道,SPFA是比较不稳定的,所以我们需要Dijkstra
Dijkstra的时间复杂度稳定在O(N^2),是一种非常理想的时间复杂度(主要是稳定)
dijstra
基本思路:
可以理解为一个DP,找到与起点距离最短距离最短的点,以此类推继续往外拓展,更新其它点对于起点的最短距离。将整张图搜完,就大功告成了。
dijstra
基本流程:
设起点是 \(s\)
\(dis_u\) 表示目前从 \(s\) 到 \(u\) 的最短路径
\(vis_u\) 表示 \(u\) 点的最短路是否已经被确定
- 初始化起点的距离 \(dis_s=0\),其它节点都是
0x3f3f3f
- 找到所有未确定最短路的点中,与 \(s\) 的距离 \(dis_u\) 最小的点 \(u\)
- \(dis_u\) 一定是起点到 \(u\) 最短的长度了。\(u\) 的最短路已确定
- 扫描 \(u\) 的所有出边 如果 \(s→u→v\) 这条路径更优 \((\) 即 \(dis_u+w(u,v)<dis_v)\) 就把 \(dis_v\) 更新为 \(dis_u+w(u,v)\)
- 重复2~4直到所有点的最短路都被确定
dijstra
的正确性证明:
本质上的思想是贪心
在每一轮更新后,还未访问到过的节点一定不优于已经访问到过的节点
而在已经访问到过的节点中 找出未确定最短路且当前 \(dis_u\) 最小的 \(u\)。由于其它点的 \(dis\) 本来就已经比 \(dis_u\) 大,边权还是非负数 它们不可能更新 \(dis_u\) 所以 \(dis_u\) 就被确定了,\(u\) 的最短路也确定了。