0
点赞
收藏
分享

微信扫一扫

【刷题】图论——最短路【证明+模板】

young_d807 2022-02-04 阅读 35
图论算法

文章目录


定义图有:n个点,m条边

单源最短路

边权为正

1.1、朴素Dijkstra O(n^2)

算法步骤

假设起点是st;已经确定到st最短距离的点在集合S中

  1. d i s [ s ] = 0 , ( i ≠ s ) d i s [ i ] = + ∞ dis[s] = 0, (i\neq s)dis[i] = +\infty dis[s]=0,(i=s)dis[i]=+
  2. for(i = 0; i < n; i ++ )
    2.1. 不在S中,距离st最近的点x
    2.2. 用x更新它连的所有点y(松弛操作):
    if(dis[y] > dis[x] + w(x, j)) dis[j] = dis[x] + w(x, y)
    2.3. x放入S

第二步循环内每次都能确定一个点x的最短距离,重复n次就能确定所有点的最短距离。

以算法导论的图为例:
在这里插入图片描述
a. 初始化dis[s]=0
b. 到s最近的就是s本身,更新s连的y和t, S = { s } S=\{s\} S={s}
c. 到s最近的是y( y : 5 < t : 8 < x : ∞ = z : ∞ y:5 < t:8<x:\infty=z:\infty y:5<t:8<x:=z:),更新y连的t、x、z, S = { s , y } S=\{s,y\} S={s,y}
d. 到s最近的是z( z : 7 < t : 8 < x : 14 z:7 < t:8 < x:14 z:7<t:8<x:14),更新z连的x, S = { s , y , z } S=\{s,y,z\} S={s,y,z}
e. 到s最近的是t( t : 8 < x : 13 t:8 < x:13 t:8<x:13),更新t连的x, S = { s , y , z , t } S=\{s,y,z,t\} S={s,y,z,t}
f. 到s最近的是x(只剩x了),结束。


算法证明

粗略证明:

  1. 如果某个点(下图中的u)由算法得到的答案不是最短路,那在理论最短路径中,u肯定是连在“比u晚进S的点”(下图中的y)后面。
    1.1. 因为如果是连在"比u先进入S的点"(下图中的x)后面,由归纳得x是最短路,x能松弛到u,算法得到得答案也是理论最短路径,矛盾。
  2. 而路径中y在u前面,边权又都是正的,算法是挑近的进S,y肯定会比u更早进S,矛盾。
  3. 因此不存在u,进S的点由算法得到的值就是实际最短路的值。

下面是严格证明:

假设u之前的点,有性质:对于所有加入S的点,在这个点加入S时,根据算法的步骤所确定的st到这个点的距离,都是最短路

记:根据算法的步骤所确定的 s t st st到点 i i i的距离 = d i s [ i ] dis[i] dis[i] s t st st到点 i i i的实际最短路= a n s [ i ] ans[i] ans[i]

那么性质可简写为:对于所有加入S的点 i i i,在 i i i加入S时,都有 d i s [ i ] = a n s [ i ] dis[i]=ans[i] dis[i]=ans[i]

在这里插入图片描述
命题如下:点 u u u加入S时, u u u是第一个使这个性质不成立的点,即 d i s [ u ] ≠ a n s [ u ] dis[u] \neq ans[u] dis[u]=ans[u]

利用反证法证明不存在这样的点 u u u

  1. u u u s t st st不同:因为 s t st st是第一个进入集合 S S S的结点, d i s [ s t ] = 0 dis[st]=0 dis[st]=0,是最短路,性质成立。
  2. 此时 S S S不是空集: u u u加进来时至少有点 s t st st
  3. 此时已经存在某条从 s t st st u u u的路径:算法每次都是找距离 s t st st最近的点,如果不存在 s t st st u u u的路径,那么 d i s [ u ] = ∞ dis[u]=\infty dis[u]= u u u不可能被加进来。
  4. 不妨设目前所有 s t st st u u u的路径中,最短的路径是 st —p1—> x —> y —p2—> u, x x x y y y的前一个点, y y y是第一个不属于 S S S的点,因此 x x x S S S中。
    ps. (p1和p2可能不包含任何边,可能 s t = x st=x st=x y = u y=u y=u,但 x x x y y y不同,p2可能重新进入 S S S)
  5. d i s [ x ] = a n s [ x ] dis[x]=ans[x] dis[x]=ans[x]:因为 u u u是第一个使这个性质不成立的点,而 x x x u u u之前且已经进入 S S S中。
  6. d i s [ y ] = a n s [ y ] dis[y]=ans[y] dis[y]=ans[y]:点 x x x进入 S S S时,进行松弛更新了 y y y,得到了 d i s [ y ] dis[y] dis[y]
    y y y s t st st—> u u u的最短路上,如果还存在其他st—p3—>y的最短路,那么st —p3—> y —p2—> u,才是st—>u的最短路,这和第4步的假设矛盾。
    因此st —p1—> x —> y就是st—>y的最短路径。
  7. a n s [ y ] ≤ a n s [ u ] ans[y]\leq ans[u] ans[y]ans[u]:因为 y y y u u u之前,且所有路径都是正的。
  8. a n s [ u ] ≤ d i s [ u ] ans[u]\leq dis[u] ans[u]dis[u]:算法估计的最短路只可能比真实的最短路长。
  9. d i s [ u ] ≤ d i s [ y ] dis[u]\leq dis[y] dis[u]dis[y]:u和y都不在S中,而算法每次都会从不在S中的点里面挑距离 s t st st最近的,也就是dis更小的,而此时 u u u正准备进 S S S,而 y y y是在之后才进 S S S。因此 d i s [ u ] ≤ d i s [ y ] dis[u]\leq dis[y] dis[u]dis[y]
  10. 根据第7、8、9步,我们得到 a n s [ y ] ≤ a n s [ u ] ≤ d i s [ u ] ≤ d i s [ y ] ans[y]\leq ans[u] \leq dis[u] \leq dis[y] ans[y]ans[u]dis[u]dis[y]
    由根据第6步的 d i s [ y ] = a n s [ y ] dis[y]=ans[y] dis[y]=ans[y],有 a n s [ y ] = a n s [ u ] = d i s [ u ] = d i s [ y ] ans[y] = ans[u] = dis[u] = dis[y] ans[y]=ans[u]=dis[u]=dis[y]
    可以看到 a n s [ u ] = d i s [ u ] ans[u] = dis[u] ans[u]=dis[u]和命题矛盾
  11. 综上不存在这样的点 u u u,因此算法所求的所有点都满足性质,即进入S的点所确定的距离都是最短路。

算法实现

在这里插入代码片

1.2、堆优化Dijkstra O(mlogn)

边权为负

2.1、Bellman-Ford O(nm)

可以处理限制只经过k条边的最短路问题。

2.2、SPFA 一般O(m)、最坏O(nm)

多源最短路

3 Floyd O(n^3)

举报

相关推荐

0 条评论