差分约束

前言

考虑单源最短路的一个性质:

在有向图中,若存在边 \(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 \(1\)+Trick \(2\)+Trick \(3\)+Dijkstra 把这题过了。

可能以后还会更新。

posted @ 2024-04-05 21:08  Po7ed  阅读(3)  评论(0编辑  收藏  举报