给您一连串的不等式组,让您找出满足该不等式的最大值或最小值。这就是差分约束要解决的问题。
引入
给出 n 个变量和 m 个不等式,就像这样
⎩⎨⎧x1−x2≤k1x3−x2≤k2x3−x1≤k3x4−x2≤k4x3−x2≤k5
让您求出满足条件的 x1…x4 中 x4−x1 的最大值。
首先想到的就是手动推,很显然,计算机是不可能模拟手动推的。
与最短路算法的联系
考虑一下最短路算法的松弛过程。
这是不是很像上面的不等式?k 就是边权,dis
数组就是那两个变量。但是符号是相反的。
这并不影响我们我们进行图论的建模。
我们只需要对于每个形如 xi−xj≤k 的不等式,从 j 到 i 连边,边权即为 k 。
这样跑一遍从 1 到 n 的最短路就是 xn−x1 的最大值。
无解的情况
存在负环即无解。
在跑 SPFA 时记录一下每个点入队的次数,如果入队次数大于点数,即存在负环。
对于各种形式的不等式
- 求最小值:需要把每个不等式转化为 xi−xj≥k 的形式,从 j 到 i 连边,边权即为 k 。然后跑一遍最长路即可。
- 求最大值:需要把每个不等式转化为 xi−xj≤k 的形式,从 j 到 i 连边,边权即为 k 。然后跑一遍最短路即可。
- 没有等号的情况:如果是 xi−xj<k 的形式,需要先转化为 xi−xj≤k−1 的形式连边。反之亦然。
- 只有等号的情况:建双向边即可。即转化为 xi−xj≤k 和 xi−xj≥k 的形式。
例题 1
[SCOI2011]糖果
传送门
思路
可以很轻易地根据差分约束系统建模。
这道题并不是求特定两个数之间的最小值,求得是最小值的总和,只需要把 dis
数组中的值加起来即为答案。
注意要开 long long
,否则会 WA 一个点。
完整代码
例题 2
种树
传送门
思路
如何建模?我们可以利用前缀和,建立 sum[b]
与 sum[e]
的关系。根据读入描述可建立模型 se−sb−1≥t (为什么要减去 1?因为是闭区间 QwQ)。
其中还有一个隐含条件,就是每座房子前最多种一棵树,所以有了这样的不等式 0≤si−si−1≤1,稍微转化一下就是两个不等式 si−si−1≥0 和 si−1−si≥−1。
需要建立一个超级源点向所有点连权值为 0 的边,这样从超级源点跑一遍最长路,最后 dis[n]
即为解。
完整代码