图论有关问题

mndzk,mndbu。

最短路相关

1. 三角形不等式

对于单源最短路,记 \(dis_i\) 为原点到 \(i\) 的最短路径长度。那么 \(\forall (u,v,w) \in E,dis_{u}+w \ge dis_v\)。且在边 \((u,v,w)\) 在最短路上时取等。这个比较显然,因为如果 \(dis_u +w < dis_v\),那么 \(v\) 按照 \(s \to u \to v\) 的方式到达会更优,不符合最短路条件。 三角形不等式可以拓展为:\(\sum\limits_{j=2}^{n}dis_{p_j,p_{j-1}}\ge dis_{p_n,p_1}\)

应用

P12043 [USTCPC 2025] 图上交互题4 / Constructive Shortest Path

显然有:\(w_{u_i,v_i} \ge f(u_i,v_i)\)。那么对于一条边 \((u_i,v_i)\),如果经过了另外两个点 \(x,y\),那么一定有 \(dis_{u_i,x}+dis_{x,y}+dis_{y,v_i}\ge dis_{u_i,v_i}\)。显然,如果存在合法解,那么 \(w_{u_i,v_i}=f(u_i,v_i)\) 是可行的。因为绕路和直接连等价。

对于合法解构造,在不知 \(f(x,y)\) 的情况下,将其设为 \(10^{100}\) 无影响。那么只需要求一遍多源最短路,看 \(dis_{u_i,v_i}\)\(f(u_i,v_i)\) 的关系即可。时间复杂度 \(O(n^3)\)

差分约束类问题

基本模型:给定若干对形如 \(x_i -x_j \le(\ge ) c\) 的限制,求可能的一组解。

根据三角形不等式,可以将 \(i\) 看成图上一点,\(x_i\) 看成超级源点 \(0\)\(i\) 的最短路。例如 \(x_i -x_j \le c\),则可以抽象成 \(x_j+c \ge x_i\)。这时 \(c\) 就是 \((j,i)\) 的边权了。那么跑最短路就可以得到一组解。

通过 SPFA 求得一组解,一定是字典序最大的解。证明略。

P5590 赛车游戏

\(m\) 条边标边权,使得 \(1\)\(n\) 的最短路与最长路长度相等。

根据三角形不等式,需要满足 \(dis_{1,u}+w_{u,v}=dis_{1,v}\) 才行。因为在 \(dis_{1,u}+w_{u,v}>dis_{1,v}\) 时,\(1\)\(n\) 的最短路不大于 \(dis_{1,v}+dis_{v,n}\),且最长路不小于 \(dis_{1,u}+w_{u,v}+dis_{v,n}\)。这两个值不能不同。

因为 \(1 \le w_{u,v}\le 9\),所以先跑一遍差分约束。得到一组可能的解。再规定 \(w_{u,v}=dis_v-dis_u\) 就行了。时间复杂度 \(O(nm)\)

AT_agc056_c [AGC056C] 01 Balanced

求个前缀和,就是需要满足 \(s_{r_i}=s_{l_i-1}+\frac{r_i-l_i+1}{2}\)。因为是前缀和,所以还有 \(s_{i-1}+1 \ge s_i \ge s_{i-1}\) 的限制。转成差分约束,有:

  1. \(s_{l_i-1}+\frac{r_i-l_r+1}{2}\ge s_{r_i}\)
  2. \(s_{r_i}-\frac{r_i-l_i+1}{2}\ge s_{l_i-1}\)
  3. \(s_i +0 \ge s_{i-1}\)
  4. \(s_{i-1}+1 \ge s_i\)

但是这种图跑 SPFA 就四了,因为 \(n \le 10^6,m \le 2\times 10^5\)

转化下式子:

\[s_{r}=s_{l-1}+\frac{r-(l-1)}{2}\\ 2s_r-r =2s_{l-1}-(l-1) \]

\(a_i=2s_i-i\)。那么条件可以写成:

  1. \(a_r=a_{l-1}\)
  2. \(a_i \le a_{i-1}+1\)
  3. \(a_{i-1}\le a_{i}-1\)

发现这样做之后,只存在 \(0,1\) 的双向边,且跑出来的最小解不可能满足 \(a_i=a_{i-1}\)。因为若 \((u,v,w)\)\(w=0\),则 \(a_u,a_v\) 奇偶性一定相同,否则一定不同。那么在存在合法解的情况下,一定不会有 \(a_{i},a_{i-1}\) 奇偶性相同。使用 01BFS 做到 \(O(n+m)\)

2. 传递闭包与可达性统计

还在追忆。

Floyd 可以维护传递闭包。具体地,维护 \(T_{u,v}\) 表示 \(u\)\(v\) 之间的可达性,那么枚举中转点 \(k\),可以在 \(O(n^3)\) 复杂度求解。

注意到 \(T_{u,v}\in \{0,1\}\)。那么使用 bitset 压位做到 \(O(\frac{n^3}{\omega})\)

对于 DAG 上可达性统计,拓扑排序的过程中维护 bitset 做到 \(O(\frac{nm}{\omega})\)

P7516 [省选联考 2021 A/B 卷] 图函数

先求 \(f(u,G)\)。点 \(v\) 会对答案贡献 \(1\),当且仅当:

  1. \(v \le u\)
  2. 存在一条 \(u\)\(v\) 的路径,满足 \(\max\limits_{x\in P(u,v)}^{}x \ge v\)
  3. 存在一条从 \(v\)\(u\) 的路径,满足 \(\max\limits_{x\in P(u,v)}^{}x \ge v\)

把点 \(x \ge v\) 看做 \(1\)\(x < v\) 看做 \(0\)。那么就是存在 \(u,v\) 之间的双向路径,满足只经过 \(1\) 的点。

对于求 \(h(G)\),考虑分开计算贡献。我们去枚举 \(v\),那么它会对所有满足下面条件的 \(u\) 产生贡献:

  1. \(u \ge v\)
  2. 只经过 \(1\) 的点,存在 \(u\)\(v\)\(v\)\(u\) 的路径。

这第二个条件很弱,因为 \(u\)\(v\) 可以看做走反图。那么将 \(0\) 的点去掉后,\(v\) 会贡献的值应该是图 \(G\) 和反图 \(G'\)\(v\) 都可达的点的数量。

维护 \(f_{u}\)\(G\)\(u\) 只走比它大的点,能到的点集。\(g_u\) 为反图的。那么 \(h(G)=\sum\limits_{u=1}^{n} |f_u\cap g_u|\)。暴力做可以做到 \(O(\frac{n^3}{\omega})\)

考虑删边。因为删的是前缀,所以一旦这个时刻 \(u\) 不能对 \(v\) 产生贡献了,那么之后就一定不可能产生贡献。启发我们维护 \(u\)\(v\) 产生贡献的最大时刻。

也就是说,我们需要维护 \((u,v)\) 同时在两个图上联通时,最小边权的最大值。显然两个图可以分别求,然后取 \(\min\)。那么 Floyd 暴力跑就可以做到 \(O(n^3)\) 预处理了。时间复杂度 \(O(n^3+m)\)

3. 最短路树与最短路 DAG

维护 \(f_i\) 为最后一次松弛 \(i\) 的点。那么一定有:\(dis_{s,f_i}+w_{f_i,i}=dis_{s,i}\)。此时 \(i\)\(f_i\) 连边后得到的有向树就是最短路树。

同理,维护所有满足 \(dis_{s,v}+w_{v,u}=dis_{s,u}\)\(v\),连边后得到的图一定是 DAG(在不包含零环的情况下)。此时最短路图上任意一棵生成树一定是最短路树。

应用

U531345 任务

先把 \(A\)\(B\) 的最短路图建出来。那么对于将其中一条链变成 \(0\) 之后的情况,显然是 \(C\) 走到了最短路图上某点,在从这个点出发通过 \(0\) 的边走到另外一个点,再从这个点走到 \(D\)。显然中途不走 \(0\) 的边,后面再走 \(0\) 的边不优。

那么忧郁最短路图是 DAG,则只需要维护可以到达 \(u\) 的点中 \(dis_{C,v}\) 的最小值。那么从 \(u\) 离开的代价就是这个值加上 \(dis_{D,u}\)。注意也可能是从 \(D\) 走到 \(C\),因为原图是无向图,而最短路图是有向图。时间复杂度 \(O(n\log n)\)

P6880 [JOI 2020 Final] 奥运公交 / Olympic Bus

首先如果不翻转随便做。

先把 \(1\)\(n\) 的最短路树建出来。考虑对翻转的边分类讨论:

  1. 边不在最短路树上。因为有向图,所以在树上的边一定不会在回来时用到,标记这些边不能翻转,跑一遍最短路即可。时间复杂度 \(O(m\log m)\)
  2. 边在最短路树上。发现最短路树上的边只有 \(O(n)\) 条。这里有个简单 trick,就是当 \(E =V^2\) 时,可以通过每次暴力找到队列中 \(dis\) 最小的点进行松弛,那么时间复杂度是 \(O(E+V^2)\) 的。这个时候枚举这 \(O(n)\) 条边,暴力跑最短路的时间复杂度 \(O(n^3)\)

同时,还有可能翻转 \(n\)\(1\) 路径上的边。和上面一样做。时间复杂度 \(O(m\log m+n^3)\)

4. 同余最短路

基本模型:给定 \(n\) 个物品 \(x_1\dots x_n\),求在可以无限使用的情况下,能够凑出 \([l,r]\) 中多少个值。即有多少个 \(c\),满足存在一组 \(a_1\dots a_n\),使得 \(c=\sum a_ix_i\)

注意到对于一个数 \(c\),如果它能凑出来,那么任意 \(c+\delta x_i\) 也能凑出来。可以发现,本质不同的 \(c\) 的个数是 \(O(x_i)\) 的。那么维护 \(f_{i}\) 表示 \(c \bmod x_1=i\) 时,\(c\) 的最小值。那么所有 \(c+\delta x_1\) 也都能凑出来。这个时候 \(u \to (u+w)\bmod x_1\),边权为 \(w\),就可以了。时间复杂度 \(O(nx_1 \log (nx_1))\)

应用

AT_arc084_b [ABC077D] Small Multiple

考虑一个数字是怎么生成的。那么可以是通过从高往低,不断 \(x \times 10 +a\) 得到。

通过这个,对于一个 \(n\) 位数,可以看做从源点走了 \(n\) 步,第 \(i\) 步的代价为 \(a_i\)。注意到 \(K \le 10^5\),那么维护 \(f_i\) 表示 \(x \bmod K=i\) 时,\(\sum a_i\) 的最小值。这个时候就可以直接上最短路了,最短路上点表示 \(x \equiv i \pmod K\) 时,\(x\) 位数和的最小值。那么按照上面那个边权建边后,源点到 \(0\) 的最短路就是答案了。

5. 杂题

AT_abc232_g [ABC232G] Modulo Shortest Path

按照 \(B\) 从小到大排序。那么对于点 \(i\),有分界点 \(k\),使得 \([1,k]\) 中任意一个点,\(i,j\) 之间的边权均为 \(A_i+B_j\)\([k+1,n]\) 中任意一个点,\(i,j\) 之间的边权均为 \(A_i+B_j-M\)

那么前后缀优化建图就可以了吧。对每个点新增两个虚点 \(i',i''\)\(i'\)\(i''\) 都向 \(i\) 连边权位 \(B_i\) 的边,表示一个点要走到 \(i\) 必须花 \(B_i\) 的代价。再对于每个点,找到上面的分界点,则一个前缀的代价均为 \(A_i\),一个后缀的代价均为 \(A_i-M\)。分别连向第 \(k\) 个点对应的 \(k'\) 和第 \(k+1\) 个点对应的 \((k+1)''\)。排序后 \((i+1)'\)\(i'\)\(0\) 的边,表示一个点花 \(A_j\) 的代价走到 \((i+1)'\),就一定能花 \(A_j\) 的代价走到 \(i'\)。同理 \(i''\)\((i+1)''\)\(0\) 的边。

这样点数是 \(3n\) 的,边数是 \(4n\) 的。然后就可以直接跑最短路了。时间复杂度 \(O(n\log n)\)

不难发现问题。\(A_i -M <0\)。也就是说,这样连边存在负权。并且 SPFA 明显卡死。那就不能这样拆开,需要将 \(A_i,B_j\) 一起算。可以不管 \(i'\),因为这些边全非负。对于 \(A_i+B_j-M\) 的边,可以尝试差分。\(i''\)\((i+1)''\)\(B_{i+1}-B_i\) 的边。再对于每个 \(i\),向对应的 \(k+1\)\(A_i+B_{k+1}-M\) 的边。\(i''\)\(i\)\(0\) 的边。这样 \([k+1,n]\) 中每个点,如果需要从 \(i\) 走过来,就一定是 \(A_i+B_{k+1}-M+B_{k+2}-B_{k+1}+...+B_{j}-B_{j-1}\)。简单化简显然是 \(A_i+B_j-M\)。这样保证了边权非负,可以做到 \(O(n\log n)\)

P3573 [POI 2014] RAJ-Rally

怎么求图上最长路。因为可以从任意节点出发,在任意节点停止。根据简单 trick,可以建立源点和汇点。源点向所有点连 \(0\) 的边,所有点向汇点连 \(0\) 的边。因为原图是 DAG,所以这么建出来仍为 DAG,且源点到汇点的最长路就是图上最长路。

维护 \(f_i\) 为源点到 \(i\) 的最长路,\(g_i\) 为汇点到 \(i\) 的最长路。那么经过边 \((u,v)\) 的最长路就是 \(f_{u}+g_{v}+1\)。枚举删掉一个点 \(x\),那么答案就是 \(\max\limits_{(u,v)\in E\land u\ne x\land v\ne x}^{}f_u+g_v+1\)。真的吗?明显假。因为没人知道 \(f_{u}\)\(g_v\) 在最大的情况下有没有经过 \(x\)

注意到这是 DAG,DAG 是可以划分成 \(S,T\) 两个集合,其中 \(S\) 包含源点,\(T\) 包含汇点。那么没被任意一个导出子图包含的边只能是 \(u \in S\land v\in T\) 的。且在不删点的情况下,最长路一定是 \(\max\limits_{(u,v)\in E \land u\in S\land v\in T}^{}f_{u}+g_v+1\)。这启示我们不断向 \(S\)\(T\) 中加点、删点,维护最长路。

具体地,一开始 \(S =\emptyset,T=\{s,e,1,2,3,\dots,n\}\)。将 \(T\) 中一个点 \(i\) 加到 \(S\) 中,先将 \(i\) 删除。此时答案应该是 \(\max\limits_{(u,v)\in E\land u\in S \land v \in T \land v\ne i}^{}f_u+g_v+1\)。然后再将 \(i\) 加入 \(S\)。但还是有问题,仍然不知道 \(u,v\) 有没有经过 \(i\)。但是发现如果强制按照拓扑序做就可以避免这种情况了。首先拓扑序小的已经在 \(S\) 中,不可能有 $s \to i \to u $ 的情况,其次 \(i\)\(T\) 中拓扑序最小的,不可能存在 \(v \to i\) 的边。所以这样处理就是对的。

如果对每条边预先处理 \(f_{u}+g_{v}+1\),则问题变成:维护加边,删边,求当前存在的边中价值的最大值。

任意维护做到 \(O(m\log m)\)

P6822 [PA 2012 Finals] Tax

AT_abc232_g 和这题啥关系。

\(P(1,n)\)\(1\)\(n\) 经过的边权。那么实际代价是 \(\sum\limits_{i=1}^{|P(1,n)+1|} \max(w_i,w_{i-1})\)。满足 \(w_0=0,w_{|P(1,n)+1|}=0\)

考虑拆点,把点 \(i\) 拆成 \(i_1,i_2,\dots i_{deg_i}\),表示最后一条边是 \(i\) 的第 \(j\) 条边。那么将 \(i\) 的每条边从小到大排序,枚举 \(u_{j}\),那么对于这条边对应的点 \(v\),可以二分找到分界点 \(k\),使得 \([1,k]\) 都有 \(\max(w_{u,v},w_{v,w})=w_{v,w}\)\([k+1,deg_v]\) 都有 \(\max(w_{u,v},w_{v,w})=w_{u,v}\)。那么 \(i_j\) 再拆成两条链,第一条从后往前依次链,第二条从前往后依次连,边权都是 \(0\),再对第一条链增加 \(w_{v,w}\) 的代价,第二条增加 \(0\) 的代价。然后对 \(u_j\) 连出去的边,第一条连增加 \(0\) 的代价,第二条增加 \(w_{u,v}\) 的代价就行了。这样点数是 \(O(\sum deg_u)\) 也就是 \(O(m)\) 级别的,大概会乘个 \(4\)。时间复杂度 \(O(m\log m)\)

posted @ 2025-11-13 22:03  harmis_yz  阅读(9)  评论(0)    收藏  举报