差分约束系统是求解不等式组的一种算法,其实就是将不等关系转化为图中的边,然后通过求最短/长路求解不等式组解的边界。
其中不等式应形如y-x<=k,然后利用最短/长路中的三角不等式建边。以最短路为例,假如我们求出了一张图中所有点到源点的最短路,若存在边<x,y>,其边权为k,那么必有dist[x]<=dist[y]+k。这是显然的,因为是最短路,假如dist[x]>dist[y]+k,那么边<x,y>就可以使得dist[x]更小。
注意上面提到的源点,我们一般还需要建一个超级源0,他到其他结点均有边,且边权为0。
如此跑最短路,解应该是非正的,跑最长路,解是非负的。其实将y-x<=k转化为x>=y+(-k),然后建一条边<y,x>,边权为-k,跑最长路效果是一样的。
不过往往,求最大值用最短路,求最小值用最长路。
不等式组可能无解,若图中出现了负环(最长路是正环),则无解。因为会有负边权和负环,所以差分约束系统一般选择SPFA算法。
附一道例题,BZOJ2330:https://www.lydsy.com/JudgeOnline/problem.php?id=2330