最短路

Defination

  • 对于一个图(管他是有向图,无向图,管他有没有环,管他边权为负与否),没有负环.

  • d i s [ i ] [ j ] dis[i][j] dis[i][j]表示 i i i出发,到 j j j最短路,满足 d i s [ i ] [ v ] ≤ d i s [ i ] [ u ] + w [ u , v ] dis[i][v]\le dis[i][u]+w[u,v] dis[i][v]dis[i][u]+w[u,v]


Algorithm

总结一下各种算法的性质:

1. D I J K S T R A DIJKSTRA DIJKSTRA

我的最爱~~~

  • 基于贪心,以点为基点“松弛”,要求边权非负,复杂度很稳定,最短路计数方便,好想又好写!!

  • 实现方式:

    -1.堆优化排序。( priority-queue \text{priority-queue} priority-queue),要打一个 v i s vis vis标记:一个点出队一次。
    复杂度: O ( ( n + m ) l o g ( n + m ) ) O((n+m)log(n+m)) O((n+m)log(n+m)),后面那个log并不会被卡边数。

    -2.set优化排序。 e r a s e erase erase代替 v i s vis vis
    复杂度: O ( ( n + m ) l o g n ∗ set常数 ) O((n+m)logn*\text{set常数}) O((n+m)lognset常数),不见得快多少,主要是好写。

  • 扩展: J o h n s o n Johnson Johnson算法让 d i j dij dij也可以跑负边权最短路。
    -1,建立 源点 S S S, ∀   i , l i n k ( S , i , 0 ) \forall \ i,link(S,i,0)  i,link(S,i,0),用 s p f a spfa spfa跑一边 S S S为起点的最短路,即为 D i D_i Di

    -2,修改边权。 ∀   e d g e i , w i = w i + ( D u − D v ) \forall \ edge_i,w_i=w_i+(D_u-D_v)  edgei,wi=wi+DuDv

    -3, d i j dij dij跑原图最短路, d i s [ u ] [ v ] = d i s [ u ] [ v ] − ( D [ u ] − D [ v ] ) dis[u][v]=dis[u][v]-(D[u]-D[v]) dis[u][v]=dis[u][v](D[u]D[v])

2.SPFA

  • 本质是以边为单位。 v i s vis vis标记改为"队列中一个点唯一存在,不重复"。

  • 复杂度: O ( m ) O(m) O(m)~ O ( n ∗ m ) O(n*m) O(nm)(卡spfa是一个出题人的自我修养)

  • 各种优化: 1.双端队列,和队首比较,选最优。2.堆优化决策点。(负权图会被卡成 O ( n ∗ m ∗ l o g n ) O(n*m*logn) O(nmlogn),真好笑)

  • 扩展: 判负环: 一个点被松弛次数超过 n − 1 n-1 n1次,说明有负环。可用 d f s dfs dfs迭代加深优化实现,或者来一个 r a n d o m − s h u f f l e random-shuffle randomshuffle。。

3.FLOYD

  • 本质:动态规划: d p [ i ] [ j ] [ k ] dp[i][j][k] dp[i][j][k],只经过编号 ≤ k \le k k的点, i , j i,j i,j最短路。

  • d p [ i ] [ j ] [ k ] = m i n ( d p [ i ] [ j ] [ k − 1 ] , d p [ i ] [ k ] [ k − 1 ] + d p [ j ] [ k ] [ k − 1 ] dp[i][j][k]=min(dp[i][j][k-1],dp[i][k][k-1]+dp[j][k][k-1] dp[i][j][k]=min(dp[i][j][k1]dp[i][k][k1]+dp[j][k][k1].

  • 复杂度: O ( n 3 ) O(n^3) O(n3)

  • 扩展:由于是动态规划,可以解决一些其他的问题。

    -1.传递闭包。 f [ i ] [ j ]   ∣ =   f [ i ] [ k ] & f [ k ] [ j ] f[i][j]\ |=\ f[i][k]\And f[k][j] f[i][j] = f[i][k]&f[k][j]

    -2.最小环: 最小环: d i s ] [ i ] [ j ] ( 不 经 过 e d g e [ i ] [ j ] ) + e d g e [ i ] [ j ] dis][i][j](不经过edge[i][j])+edge[i][j] dis][i][j](edge[i][j])+edge[i][j],显然可以用 f l o y d floyd floyd的性质。

    -3.规定边数的最短路 ∣ e d g e ∣ ≤ 1 e 9 |edge|\le1e9 edge1e9,把边看作矩阵,矩阵相乘即为 A r   ∗   A c = A r + c A^r\ *\ A^c=A^{r+c} Ar  Ac=Ar+c


Application

1.单源最短路,单源 的理解:一个集合到另一个之间的最短路。
详见:GZOI2019旅行者

2.最短路树:每个点只会由一个点更新,我们显然可以连成最短路树。最短路树不只能确定最短路关系。(safe trave) 一些简单的问题可以通过最短路树解决。(最小环长度)

3.边权为1时,最短路树演变成bfs树。可以借以分析最终的最短路情况。(比如在bfs树上做一个dp(10.9测试 期望dp)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值