差分约束系统学习笔记
用于解决 \(n\) 个变量有 \(m\) 个形如 \(x_i\le x_j+k\) 的限制的解。
发现这个限制和最短路中 \(dis_v\le dis_u+w\) 的三角不等式很相像,考虑将 \(x_i,x_j\) 看作两个点,然后连一条边象征这个限制(具体怎么连后面会说),这样跑最短路之后就满足所有限制了。
不难发现对于一组解,将其整体加上 \(d\) 都是满足要求的。
所以题目问法一般有两种:要求 \(x_i\le a_i\),求最大的解。或者 \(x_i\ge a_i\),求最小的解。
先考虑前者。
然后我们考虑建一个虚点 \(x_0\),然后连一条 \(x_0\to x_i\) 边权为 \(a_i\) 的边,相当于增加了 \(n\) 条限制 \(x_i\le x_0+a_i\)。
若我们令 \(x_0=0\) 就能够满足条件,具体来讲就是让 \(x_0\) 作为源点,\(dis=0\)。
然后对于一条限制 \(x_i\le x_j+k\),我们建一条 \(x_j\to x_i\) 的边,边权为 \(c\)。
然后我们以虚点为源点跑一遍单源最短路,跑出来的就是最大解。
然后考虑后者,还是考虑先建立虚点 \(x_0\),然后连一条 \(x_0\to x_i\) 边权为 \(a_i\) 的边,不过这条边的含义是 \(x_i\ge x_0+a_i\)。
而这满足的是最长路的三角不等式 \(dis_v\ge dis_u+w\)。
于是我们考虑 \(x_i\le x_j+k\) 这条限制怎么转化满足最长路的三角不等式。两边取反之后移项转化为 \(x_j\ge x_i-k\)。
所以连一条 \(x_i\to x_j\) 的边,边权为 \(-k\) 即可。
然后我们以 \(x_0\) 为源点,跑一遍单源最长路即可。
跑最短路的时候需要注意负环,跑最长路的时候需要注意正环。
不难发现这两种情况化简之后都是矛盾的,即无解。
所以需要先用 SPFA 判负环,复杂度最坏是 \(O(n^2)\) 的。

浙公网安备 33010602011771号