正题
这两个为什么要放在一起讲?
这两个都可以处理有负边的多源最短路.
但是
F
l
o
y
d
Floyd
Floyd 好像比
J
o
h
n
s
o
n
Johnson
Johnson 最短路的用处更大,尤其是在最小环问题上。
Floyd
简简单单的两行代码,蕴藏了很多玄机?
for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
首先第一行枚举的是中间的转移点,第 k k k 次处理完之后,你就可以得到端点为 x x x , y y y ,中间转移点只在 [ 1 , k ] [1,k] [1,k] 的最短路.
根据这个性质,我们可以做很多事情,因为这代表着每个
k
k
k 之间都是独立的,我们甚至可以以想要的顺序枚举这个
k
k
k ,那么每一时刻得到的最短路就是端点为
x
x
x ,
y
y
y ,中间转移点为 已枚举过的点
的最短路.
所以我们可以带个
log
\log
log 用线段树分治来做类似于 转移点不为k的多源最短路
,可删点/加点可离线多源最短路
。
无向图的最小环也可以用 F l o y d Floyd Floyd 很好地解决(先排除自环和重边,其次不讨论两元环),可以先看看具体代码:
for(int k=1;k<=n;k++){
for(int i=1;i<k;i++)
for(int j=1;j<i;j++)
ans=min(ans,dis[k][i]+dis[j][k]+f[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
如果为有向图,那么就将第三行的
i
i
i 改成
k
k
k 。(因为允许二元环了,而且不能确定
k
k
k 连接的两个点的大小关系)。
看起来好像就加了那三行,因为处理
k
k
k 之前已经处理好了端点为
x
,
y
x,y
x,y ,中间点为
[
1
,
k
)
[1,k)
[1,k) 的最短路,所以现在如果能找到一条
x
→
y
x\to y
x→y 的路径,满足路径上的全部点都
<
k
<k
<k,那么就可以用
k
k
k 来更新,每一个环会在环的最大端点被算多次。所以只能做取
min
\min
min 类似的操作
Jhonson最短路
也是多源最短路的一种,如果没有负边,那么就直接对 n n n 个点跑 D i j k s t r a Dijkstra Dijkstra 即可,否则我们可以用 S P F A SPFA SPFA 先跑出每个点的距离,根据这个重设边权,再跑 D i j k s t r a Dijkstra Dijkstra 。由于 S P F A SPFA SPFA 的时间复杂度为 O ( n m ) O(nm) O(nm) ,而对于每个点跑 D i j k s t r a Dijkstra Dijkstra 的时间复杂度是 O ( n ( n + m ) log m ) O(n(n+m)\log m) O(n(n+m)logm) , 所以 S P F A SPFA SPFA 的时间复杂度不在瓶颈上, J h o n s o n Jhonson Jhonson 最短路的时间复杂度也是 O ( n ( n + m ) log m ) O(n(n+m)\log m) O(n(n+m)logm)
说说怎么重设边权才合理,首先选所有缩强联通分量成 D A G DAG DAG 后,在所有入度为 0 0 0 的联通块中各找一个点作为起始点(无向图则不用考虑,因为必缩成一个点,这也是为什么 J h o n s o n Jhonson Jhonson 最短路一般用在无向图的原因),假设初始点集为 S S S ,跑出其他点到 S S S 的最短距离 d i s [ i ] dis[i] dis[i],对于一条边 ( x , y , c ) (x,y,c) (x,y,c),重设边权为 d i s [ x ] − d i s [ y ] + c dis[x]-dis[y]+c dis[x]−dis[y]+c ,因为 d i s [ y ] ≤ d i s [ x ] + c dis[y]\leq dis[x]+c dis[y]≤dis[x]+c,所以有重设后的边权 ≥ 0 \geq0 ≥0 ,可以跑 D i j k s t r a Dijkstra Dijkstra ,对于一条路径而言,中间的 d i s dis dis 会两两相消,只剩下 d i s [ u ] − d i s [ v ] + ∑ c dis[u]-dis[v]+\sum c dis[u]−dis[v]+∑c ,前面两项是定值,要求式子最小相当于要求最后一项最小。
J o h n s o n Johnson Johnson 是个处理有负边多源最短路的强有力的工具。