前言
这是一篇学习小记。(如果你很赶时间直接跳过前言)
由于本蒟蒻之前没有接触过这类题目,所以最近被一道题虐了一下,然后学习了。
其实这个名字很耳熟,只是在我小的时候,听说了,却没有去学习。
好吧,其实现在才这个东西是个非常基础的东西,但是它的思路极为巧妙。
例题
首先来看一道题。
有一段长度为n的序列,点分为特殊点和一般点。有q个提示,提示形如(x,y,c)的三元组,表示序列中的区间[x,y]中至少有c个特殊点。提示保证特殊点的分配方案唯一。现在要求哪些点是特殊点。
差分约束系统
我们设
s[i]
表示
[1,i]
中有
s[i]
个特殊点。
那么我们的提示
(x,y,c)
可以转换为这样的约束:
s[y]−s[x−1]≥c
当然,还有一些隐含的约束条件:
∀i∈[1,n],0≤s[i]−s[i−1]≤1
具体如何约束,可以这样构图:
对于三元组,令
x−1
向
y
连一条长度为
对于隐含约束,令
i−1
向
i
连一条长度为
然后跑一边最长路,求出了所有的
s
,若
至于这样做的原理,可以用最短(其实可能是最长)路的性质来解释。
设有两个点
u,v∈G
,
dis[u]
表示源点到
u
的最长距离,
那么
恒成立。
而我们的约束化成一般形式即
移项,恰好与 1 式等价。所以这就是我们将
当然具体题目中因题而定到底是最短路还是最长路。