Part 2.5.1 负环

当一张图中有负环时,这张图中经过负环的两点间最短路就不存在。因为可以无限次经过这个负环,使代价不断减小。

在三种最短路算法中,SPFA是唯一一种可以处理负环的算法。

由SPFA的过程,每个点最多会被其他点各更新一次,即入队次数不会超过 n n n

因此如果一个点的入队次数达到了 n + 1 n+1 n+1,就说明图中存在负环。

SPFA判负环的复杂度是 O ( n m ) O(nm) O(nm)

例题2.5.1 [FAIOJ30086]判断负环

模板题。

例题2.5.2 [FAIOJ30085]虫洞

本题判断的就是起点到起点的距离是否小于0

注意,有负环并不意味着条件成立。例如:

1
3 0 3
1 2 1
2 3 -1
3 2 -1

虽然有负环 ( 2 , 3 ) (2,3) (2,3),但仍然不能回到 1 1 1

我们从第一个入队次数大于 n n n的点开始搜索,如果这个点可以到达 1 1 1号点,则YES。否则NO

复杂度 O ( n m ) O(nm) O(nm)

例题2.5.3 [HNOI2009][FAIOJ20900]最小圈

求无向图最小平均环长

“最小化平均值”→二分答案。

然后按01分数规划的套路把所有边权都减去答案 x x x

则问题转化为是否存在环。如果存在,则答案上调;否则答案下调。

所以把所有边权取反,SPFA判负环即可。

复杂度 O ( n m log ⁡ W ) O(nm\log W) O(nmlogW)

Part 2.5.2 差分约束

给出一些整数变量和一些不等关系:

x 1 , x 2 , … , x n x_1,x_2,\dots,x_n x1,x2,,xn

x i − x j ≤ w x_i-x_j\leq w xixjw

我们把所有的变量看成<stron>,关系看成。</stron>

把变量的值看成最短路,则有 d i s i ≤ d i s j + w dis_i\leq dis_j+w disidisj+w

因此对于每个不等关系都连接一条 i i i j j j的边权为 w w w的边即可。

例题2.5.4 [SCOI2011]糖果

这是差分约束的模板题。

如果 d i s u = = d i s v dis_u==dis_v disu==disv,可直接用并查集合并这两个点。

如果 d i s u ≤ d i s v dis_u\leq dis_v disudisv就从 v v v u u u连一条 0 0 0的边。

如果 d i s u < d i s v dis_u<dis_v disu<disv,由于糖果的数量全是整数,所以就是 d i s u ≤ d i s v − 1 dis_u\leq dis_v-1 disudisv1,即从 v v v u u u连一条 − 1 -1 1的边。

如果有负环就输出-1。最后求出所有最短路之和,再加上最短路的最小值加1 n n n(因为每个数至少为 1 1 1)即可。

复杂度 O ( m ) O(m) O(m)(边权都是 01 01 01所以是线性的)。

例题2.5.5 [FAIOJ30087]Intervals

p i = 1 p_i=1 pi=1表示第 i i i个数被选中, = 0 =0 =0表示没被选中。

则有 ∑ i = l r p i ≥ c \sum_{i=l}^r p_i\geq c i=lrpic

看到区间和就可以想到前缀和优化。所以设 s i = ∑ i = 1 i p i s_i=\sum_{i=1}^i p_i si=i=1ipi

则有 s r − s l − 1 ≥ c s_r-s_{l-1}\geq c srsl1c,即 s l − 1 ≤ s r − c s_{l-1}\leq s_r-c sl1src。从 r r r l − 1 l-1 l1 − c -c c的边即可。

同时由于 p i ∈ 0 , 1 p_i∈{0,1} pi0,1,故有 s i + 1 − 1 ≤ s i ≤ s i + 1 s_{i+1}-1\leq s_i\leq s_{i+1} si+11sisi+1。同样连边即可。

于是转化为标准的差分约束模型。求出最短路后答案即为 s n − s 0 s_n-s_0 sns0

复杂度 O ( n m ) O(nm) O(nm),随机数据下接近 O ( m ) O(m) O(m)

例题2.5.6 [FAIOJ30090]layout

首先依题意建图。把 ≥ \geq 的关系转化为 ≤ \leq 再连边。

注意题面中 p 1 ≤ p 2 ≤ ⋯ ≤ p n p_1\leq p_2\leq \dots \leq p_n p1p2pn也要连边。

对于两种无解:

如果存在负环,则输出-1

如果不存在负环且 1 1 1 n n n不连通(即 d i s n = i n f dis_n=inf disn=inf),则输出-2

其他情况输出 d i s n dis_n disn即可。

复杂度 O ( n m ) O(nm) O(nm),随机数据下接近 O ( m ) O(m) O(m)