QBXT 2018春季DP&图论班 2018.4.29 --- 最短路&差分约束

*钟皓曦老师授课*

常见最短路算法:

Floyd → O(n^3)

Bellman-Ford → O(nm)

Dijkstra → O(n^2+m)

Dijkstra-Heap → O((n+m)log(n+m))

SPFA → O(km) 随机图 (k一般为2) 可以判负环→若一个点进队列次数超过n次,则有负环。

     O(nm) 精心构造的数据

→判断选用哪种算法:

if(n<=100) Floyd;

else if(无负权) Dijkstra-Heap;

  else SPFA;

①单源最短路可以求解多源最短路问题。

②一点到另一点的最短路,最多经过n-1条边。

  →证明:若路径包含的边数>=n,说明有环,我们可以去掉环之后直接走。因此最短路不存在环,也就最多只有n-1条边。

③求最短路一定无负环,求最长路一定无正环。但可以有正负权值的边。

次短路(次短简单路,即无重复点):

①枚举每一条边,删除后跑最短路,最后取min O(n*(n+m)log(n+m))。

②令dis[u][0]表示从起点到u的最短路,dis[u][1]表示从起点到u的次短路。

 

设W=dis[v][0]+e[i].w

当W∈左集合时 即新更新的最短路<之前最短路<之前次短路 ∴dis[v][1]=dis[v][0],dis[v][0]=W

当W∈中间集合时 即之前最短路<新更新的最短路<之前次短路 ∴dis[v][1]=W dis[v][0]不变

当W∈左集合时 即之前最短路<之前次短路<新更新的最短路 ∴dis[v][1]和dis[v][0]都不变

任何一个点的次短路可能有多段次短路组合而成,因此最终ans还要用次短路更新一遍

PS.对于次短非简单路,用A*或ZEN(蒙特卡洛)算法,不考,而且我也不会。。。。

K短路:(目前不会。。。,但方法和上面类似)

差分约束:

给定n个变量,m个形如vi-vj</<=/>/>=/= k 的约束条件,令v1=0,求vn最小/最大是多少。

<=>n个点,m条边,从v1号点出发,问vn的最长路/最短路是多少。

例:v1-v3>=3   ①v1>=v3+3 根据最长路三角不等式,v3向v1连一条边权为3的边。建完图后跑最长路

       ②v3<=v1+(-3) 根据最短路三角不等式,v1向v3连一条边权为-3的边。建完图后跑最短路、

最大值<=>最短路  若存在负环,则最大值为无穷大

最小值<=>最长路  若存在正环,则最小值为无穷小

例:{v1-v2>=3 ; v2-v3>=3 ; v1-v3>=2 }

①最大值

{v2<=v1+(-3) ; v3<=v2+(-3) ; v3<=v1+(-2)}

∵从v1到v3的最短路为-6

∴ v3 max=-6

②最小值

{v1>=v2+3 ; v2>=v3+3 ; v1>=v3+2}

∵从v1到v3的最长路不存在

∴v3 min=  -

常见连边方式:

vi-vj>=k -> vi>=vj+k or vj<=vi+(-k)

vi-vj>k -> vi-vj>=k+1

vi-vj=k -> vi-vj>=k&&vi-vj<=k -> vi>=vj+k&&vi<=vj+k 连两条边,形成一个零环,使两者最短/长路相等

vi-vj<=k

vi-vj<k ->vi-vj<=k-1

猜你喜欢

转载自www.cnblogs.com/Loi-Brilliant/p/8999207.html