关于差分约束的一切
观前须知
笔者的博客主页
声明
本文使用 CC BY-NC-SA 4.0 许可。
本文为笔者在 OI 学习中的复习向学习笔记。
部分内容会比较简略。
如有好的习题会不断补充。
知识简介
差分约束解决这样一类问题:
给定一个 n 元一次不等式组,让你求出一组解/判定是否有解/算出某个数的最值/算出和的最值……
先从最简单的开始:
那么怎么做呢?
发现对于形如 \(x_i - x_j \le c\) 的一个不等式可变形为 \(x_i \le x_j + c\)。
对于一个这样的不等式组:
可以推出 \(x_1 \le x_3 + \min(c_1 + c_2,c_3)\)。
联想一下,这个式子有什么意义呢?
来看这张图:
不难发现,有 \(x_1 \le x_3 + \operatorname{Dis}(x_1,x_3)\)
那么我们可以把三个变量转换为三个点,对于每个约束两个变量关系的不等式,变为图上的一条边!
考虑最短路中的这个式子: \(dis_v \le dis_u + w\)
那么一个形如 \(x_i - x_j \le c\) 即 \(x_i \le x_j + c\) 的式子,
就可以变成图上一条从 \(j\) 指向 \(i\),权值为 \(c\) 的边!
同理,一个形如 \(x_i - x_j \ge c\) 的式子, 可以变为一条从 \(i\) 指向 \(j\),权值为 \(-c\) 的边。
那么图就可以建出来了。
(如果涉及到 \(x_i - x_j < c\) 的式子,可以考虑变为 \(x_i - x_j <= c - 1\) 处理)
值得一提的一个性质:
一个这样的不等式组要不然无解,要不然有无数多组解。
因为只要有一组解 \(\{ x_1,x_2,x_3,\cdots,x_n\}\),
我们对于每个变量都加上一个相同的值变为 \(\{ x_1+d,x_2+d,x_3+d,\cdots,x_n+d\}\),
不难发现仍然是满足原不等式组的。
那么现在考虑什么情况下无解。
对于这样一个不等式组:
由第一个和第二个不等式相加可以推出 \(x_1 - x_3 \le -2\),
然而再和第三个不等式相加一下会变成 \(0 \le -1\),显然无解。
扩展一下,对于这样一个不等式组:
把这 n 个不等式全部相加会变成 \(0 \le \sum c_i\),当且仅当 \(\sum c_i < 0\)时无解。
那么可以发现,这在图上对应了一个负环。
所以当且仅当建出来的图上存在负环时无解。
判负环用 SPFA,对于不连通的图,添加一个超级源点,
从超级源点向所有点连权值为 \(0\) 的边,然后从超级源点跑最短路即可。
若无负环,跑出来的 dis 数组即为一组解。
那么这道板子题,我们就解决了。
代码见:笔者的板子库。
但是还不够。
当我们固定源点的值后,我们就可以求出所有点与源点的差的最值。
求最小值,则跑最长路,求出一个 \(dis_u \ge x\) 的下界。
(这里最长路可以把图的边权全部取相反数,再跑最短路算出)
求最大值,则跑最短路,求出一个 \(dis_u \le x\) 的上界。
如果要求所有变量和的最值呢?
例如令所有变量都为非负整数,求最小的变量和(见下面的习题)。
求最小值,我们跑最长路。
一个 \(x_i \ge x_j + c\) 的式子,变为图上一条从 \(j\) 连向 \(i\),权值为 \(c\) 的边(与小于号的形式类似)
建立超级源点,向各点连权值为 \(0\) 的边,并钦定该源点的值为 \(0\) (在代码里体现为dis[0] = 0
),相当于让各个点的值都非负。
接下来从超级源点跑最长路,发现 dis 数组正好就是每个点能取的最小值,求和即为答案。
总结一下:
由于通常要跑 SPFA,所以差分约束的数据范围一般不会太大。
先确定要跑什么路,再建图。
重点在于建图的时候不要漏掉题目中的隐藏条件。
习题
YbtOj 1509 Intervals
对于 \(0\) 到 \(5\times 10^4\) 的每个值建一个变量 \(s_i\) 表示前缀和。
则题目中的条件可变为 \(s_b - s_{a-1} \ge c\)。
注意隐藏条件:\(s_i \le s_{i+1}\) 以及 \(s_{i+1} - s_i \le 1\)。
建超级源点跑最长路,答案即为 \(s_{5\times 10^4}\)
细节:
由于有 \(s_{-1}\) 存在,对于所有节点编号加一再建图。
Luogu P3275 【SCOI2011】 糖果
求最小变量和,跑最长路。
根据题意建图,对于 \(x_a < x_b\) 的条件变为 \(x_a \le x_b - 1\)。
见超级源点跑最长路,答案为 \(\sum dis_i\)。
这道题数据范围较大,差分约束会被 Hack 掉
然而笔者特判自环 + SPFA SLF-swap优化冲过去了
USACO 05DEC Layout G
令 \(d_i\) 表示前缀距离。
按照题意建图,隐藏条件 \(d_i - d_{i+1} \le 0\)。
建超级源点跑最短路,有负环则无解。
对于 1 号节点跑最短路,若与 n 号节点联通则 \(dis_n\) 即为答案,否则两点间距离可以任意大。