差分约束简要笔记
概述
用来算形如:
\[\begin{cases}
x_i \le x_j+c\\
x_i \ge x_j+c
\end{cases}
\]
类似的不等式组。
做法
- 对于 \(x_i \le x_j + c\),由 \(j\) 向 \(i\) 连出一条 \(c\) 的边。
- 对于 \(x_i \ge x_j+c\),变化为 \(x_j \le x_i-c\)。由 \(i\) 向 \(j\) 连出一条 \(-c\) 的边。
- 建立一个超级原点 \(s\),由 \(s\) 向每个点连出一条 \(0\) 的边。
做完之后固定原点值为 \(0\) 跑 SPFA 最短路即可。跑出来的 \(dis\) 为该点与原点差的最大值。
如果想要最小,所有边权取相反数然后跑 SPFA 最短路即可(其实就是最长路)。跑出来的 \(dis\) 为该点与原点差的最小值。
如果想要全局和最小,我们考虑对于 \(x_i \ge x_j+c\),由 \(j\) 向 \(i\) 连出一条 \(c\) 的边;建立一个超级原点 \(s\),由 \(s\) 向每个点连出一条 \(0\) 的边。固定原点值为 \(0\) 跑最长路。\(dis\) 之和为答案。
优化
如果边权全部为正,考虑缩点。
发现但凡一个 SCC 里面存在一条边为正,那么 SCC 必然存在正环,直接没掉。
如果没有,那么整个 SCC 值相等,于是顺序跑拓扑 + DP,时间复杂度 \(O(km) / O((n + m) \log n) \to O(n + m)\)。

浙公网安备 33010602011771号