前置知识: 最短路问题、SPFA判环,为了保证学习效果,请保证已经掌握前置知识之后,再来学习本章节!
引出
当我们遇到一个不等式组,比如下面这个
\begin{cases} x_{1}-x_{3} \leq 5 \\ x_{1}-x_{2} \leq 2 \\ x_{2}-x_{1} \leq 0 \\ x_{2}-x_{3} \leq 2 \\ x_{3}-x_{2} \leq-1 \\ x_{3}-x_{1} \leq -2 \end{cases}⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧x1−x3≤5x1−x2≤2x2−x1≤0x2−x3≤2x3−x2≤−1x3−x1≤−2
怎么进行求解?
我们可以很容易地想到:
给其中一个变量赋一个具体的值,然后再逐渐估测其他变量的值,并不断修改。
比如:
-
先给 x_{1}x1 任意赋一个值,比如令 x_{1}=0x1=0,之后根据 x_{1}-x_{3} \leq 5x1−x3≤5,x_{1}-x_{2} \leq 2x1−x2≤2 ,令 x_3=-5,x_2=-2x3=−5,x2=−2,又因为 x_{2}-x_{1} \leq 0,x_{3}-x_{1} \leq -2x2−x1≤0,x3−x1≤−2,发现这组解满足条件。
-
根据 x_{2}-x_{3} \leq 2x2−x3≤2,x_3x3 改为 -4−4。
-
发现 x_{3}-x_{2} \leq-1x3−x2≤−1 也满足条件
-
解得,x_1=0,x_2=-1,x_3=-4x1=0,x2=−1,x3=−4 为其中一组解。
然而,这样的方法只适合于规模较小的时候,而且是在猜的基础上的,这样也没有办法来解出题目。
我们观察下这些不等式,像在最短路里的三角不等式,于是,发现了这些性质:
我们设 disdis 数组代表长度,跟最短路里的 disdis 概念一样。
dis_v \leq dis_u+w(u \rightarrow v) \iff dis_v-dis_u \leq w(u \rightarrow v)disv≤disu+w(u→v)⟺disv−disu≤w(u→v)
所以,我们只要对于每个不等式 x_i-x_j \leq yxi−xj≤y,连一条从 jj 到 ii 长度为 yy 的边,跑一遍最短路,即可得到一组解。
备注:我们设 cntcnt 数组来表示这个点记录了几次,如果这个图有负环,说明 cnt_i \geq ncnti≥n,则要输出无解。
这就是差分约束算法的重要思想。
差分约束
差分约束定义
差分约束(Difference-Constraints),即给出对 nn 个未知数,mm 组形如 x_{c_k}-x_{c'_k}\leq y_kxck−xck′≤yk 的约束不等式,形如
\begin{cases} x_{c_1}-x_{c'_1}\leq y_1 \\ x_{c_2}-x_{c'_2} \leq y_2 \\ \cdots\\ x_{c_m}-x_{c'_m}\leq y_m\end{cases}⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧xc1−xc1′≤y1xc2−xc2′≤y2⋯xcm−xcm′≤ym
的不等式组,其中,y_kyk 是常数(可以是非负数,也可以是负数)。
我们要解决的问题是:求一组解 x_1=a_1,x_2=a_2,...,x_n=a_nx1=a1,x2=a2,...,xn=an,使得所有的约束条件得到满足,否则判断出无解。
差分约束系统的定义
如果一个系统由 nn 个变量 a_1,a_2,\cdots,a_na1,a2,⋯,an 和 mm 个约束条件组成,每个约束条件均为形如 a_i−a_j≤kai−aj≤k 的不等式(i,j \in [1,n]i,j∈[1,n],kk 为常数),则称其为 差分约束系统。
换句话说,差分约束系统是 求解关于一组变量的特殊不等式组 的方法。
差分约束与图上最短路问题的关系
假设图上给定两点 ii 和 jj,它们之间有一条从 jj 指向 ii 的有向边,边权为 cc,且 图上不存在负环。那么,