差分约束系统

前言

这是一篇学习小记。(如果你很赶时间直接跳过前言)
由于本蒟蒻之前没有接触过这类题目,所以最近被一道题虐了一下,然后学习了。
其实这个名字很耳熟,只是在我小的时候,听说了,却没有去学习。
好吧,其实现在才这个东西是个非常基础的东西,但是它的思路极为巧妙。

例题

首先来看一道题。

有一段长度为n的序列,点分为特殊点和一般点。有q个提示,提示形如(x,y,c)的三元组,表示序列中的区间[x,y]中至少有c个特殊点。提示保证特殊点的分配方案唯一。现在要求哪些点是特殊点。

差分约束系统

我们设 s[i] 表示 [1,i] 中有 s[i] 个特殊点。
那么我们的提示 (x,y,c) 可以转换为这样的约束: s[y]s[x1]c
当然,还有一些隐含的约束条件:
i[1,n],0s[i]s[i1]1
具体如何约束,可以这样构图:
对于三元组,令 x1 y 连一条长度为 c 的边;
对于隐含约束,令 i1 i 连一条长度为 0 的边, i i1 连一条长度为 1 的边。
然后跑一边最长路,求出了所有的 s ,若 s[i]s[i1]=1 ,则说明 i 是一个特殊点,其实 s 就相当于普通最短路中的 dis
至于这样做的原理,可以用最短(其实可能是最长)路的性质来解释。
设有两个点 u,vG dis[u] 表示源点到 u 的最距离, w(u,v) 表示 (u,v) 的边权。
那么

dis[u]dis[v]+w(u,v)   (1)

恒成立。
而我们的约束化成一般形式即
s[u]s[v]c

移项,恰好与 1 式等价。所以这就是我们将 c 作为 w(u,v) 的原因。
当然具体题目中因题而定到底是最短路还是最长路。

你可能感兴趣的:(最短路,构图,差分约束系统)