前言
考虑单源最短路的一个性质:
在有向图中,若存在边 \(u\to v\),边权为 \(w\),则 \(\mathit{dis}_u+w\ge\mathit{dis}_v\)。
正确性是显然的,因为如果反之 \(\mathit{dis}_u+w<\mathit{dis}_v\),我们就可以令 \(\mathit{dis}_v\gets\mathit{dis}_u+w\),原先的就不是最短路了,与题设矛盾。
那么怎么使用这个性质呢?
正文
当题目中出现形如
\(m\) 个限制条件,每个限制条件形如:\(a\ge b,a>b,a\le b,a<b,a=b\)。
时,就可以建图跑最短路。例如 \(a\ge b\) 就让 \(a\) 向 \(b\) 连权为 \(0\) 的边,\(a>b\) 就让 \(a\) 向 \(b\) 连权为 \(1\) 的边(前提是 \(a,b\in \Bbb{Z}\))。
例题:Luogu P5960 【模板】差分约束
直接连边跑最短路即可。但观察到无法快速确定一个源点,使得从它开始可以遍历到每个点。
Trick \(1\):可以建立超级源点 \(0\),让 \(0\) 向每一个点连边。如果怕被队列优化 Bellman-Ford 被卡还可以 random_shuffle()
一下 \(0\) 的出边。
例题:Luogu P1993 小 K 的农场
同理,但只需要判负环即可。直接上队列优化 Bellman-Ford。
例题:Luogu P3275 [SCOI2011] 糖果
(笔者由于懒,还未 AC 此题。不保证下面的话完全正确。)
依然考虑差分约束。但本题可以把队列优化 Bellman-Ford 卡爆!怎么办?
两种方案:
Trick \(2\):变正权边。
考虑到此题边权仅有 \(\{0,-1\}\),考虑将边权转为非负。事实上是可行的,只需将 \(-1\to 1\) 即可。
若有限制条件 \(a>b\),则一般情况下是转化为 \(a-1\ge b\),从 \(a\to b\) 连边,边权为 \(-1\)。
转化后跑最长路,从 \(b\to a\) 连边,边权为 \(1\)。此时满足条件 \(b+1\le a\),与原条件等价。这样就转化成了非负权单源最长路。
笔者试图使用 dijkstra 水过,但各 T(很神奇地被卡了),M(判不了正环) 了一个点。不知道有没有大佬知道解决方案。
Trick \(3\):配合 Tarjan 缩点。
以下题解使用了 Trick \(2\),当然不用应该也可以做。
先缩点,每个 SCC 内部如果出现了一条 \(u\) 到 \(v\) 的边权为 \(1\),根据 SCC 的定义,一定还存在一条 \(v\) 到 \(u\) 的路径,由于边权 \(\ge 0\),所以一定会出现一个正权环,则这个差分约束系统无解。
否则的话,发现 SCC 内部变量取值一定是相同的,那么问题变成了一个 DAG 上最长路,拓扑排序即可。
——来自该题题解
就很强。
可能以后还会更新。
标签:连边,边权,差分,约束,Trick,ge,例题 From: https://www.cnblogs.com/chargedcreeper/p/-/diff-constraints