差分约束进阶

三步法求解差分约束

  1. 找不等式关系,确定是最短路还是最长路
  2. 将不等式转换为熟悉的式子建边
  3. 跑最长路或最短路

T712556 AT_abc216_g [ABC216G] 01Sequence

找到一个长度为 \(n\)\(01\) 数列,是的满足 \(m\) 个条件 \(L_i\)\(R_i\) 至少有 \(X_i\)\(1\) , 且1的数量最小,输出这个数列, 一定有解

先找不等式关系, 令 \(s_i\) 表示前 \(i\) 个数列里有多少个 \(1\),就有一下两个不等关系

\[[l, r]之间\;\;s_r - s_{l-1} \ge x \]

\[0 \leq s_i - s_{i - 1} \leq 1 \]

第二个好理解,用\(s_i - s_{i-1}\) 表示 \(i\) 号位的 \(1\) 个数, 因为只能选择放和不放 \(1\) 所以在 有这个关系

补充
\(a \leq b+c\) , 建边 \((b, a, c)\) ,跑最短路
\(a \ge b+c\) , 建边 \((b, a, c)\) , 跑最长路

这题类似之前的 种树 要让数量尽可能少, 所以也按最长路来, 把不等式转换成 \(a \ge b +c\) 的形式建边于是要建

\[(r, l-1, x) \]

\[(i,i-1,0), (i-1,i,-1) \]

这些边

\(dis_{i+1} - dis_i\) 就是第 \(i\) 个位置的答案


发现不对, \(n \leq 2e5\), \(spfa\) 不行,想到 \(Dijkstra\)
边权有正有负,怎么办?
把统计 \(1\) 的数量 改成统计 \(0\) 的数量跑最短路

最短路找至多,最长路找至少,因为要让 \(1\) 的数量至少, 随意就是让 \(0\) 的数量至多,所以跑最短路

重新来改不等式, 令\(s_i\) 表示 \(0\) 数量的前缀和
\([l,r]\)\(0\) 个数 : \(s_r - s_{l-1}\)
所以
\([l,r]\)\(1\) 个数 : \((r-l+1) - (s_r - s_{l-1})\)
所以按照限制 \(1\) 个数 \(\ge\) \(x\)

\[(r-l+1)-(s_r-s_{l-1})\ge x \]

转成熟悉的格式

\[s_r-s_{l-1}\leq (r-l+1) - x \]

所以建立\((l-1,r,(r-l+1)-x)\) 这条边
另外的那个式子可以变成

\[s_i \leq s_{i-1} + 1 \]

\[s_{i-1} \leq s_i + 0 \]

所以建 \((i-1,i,1) ,\;(i,i-1,0)\) 两条边
边权都一定是正数, 从 \(0\) 出发跑 \(Dijkstra\), 每一个位置的 \(0\) 的个数是 $$dis_i - dis_{i-1}$$
个数是\(1\)输出\(0\),是\(0\)输出\(1\)

P5590 赛车游戏

任意路径不一定是最短路径,等长 $\Rightarrow $ 等长的所有路径都是最短路
要满足上面条件,那么最短路是对于每一条边都满足条件 \(dis_u + w = dis_v\) $\Rightarrow $ \(w = dis_v - dis_u\)
\(1 \leq w \leq 9\)
所以找到了不等关系 !!!
\(1 \leq dis_v - dis_u \leq 9\)
转成

  • \(dis_u \leq dis_v - 1\)
  • \(dis_v \leq dis_u + 9\)
    建边
  • \((v, u, -1)\)
  • \((u,v,9)\)

还有一些边不在 \(1\)\(n\) 的路径上, 这些边想填什么填什么, 不要建边, 它对最短路没有影响, 不然会出现一个单独的负环在外面,导致整张图判断成无解

怎么知道那些点在路径上?

  • 正向建图, 从 \(1\) 出发染色,标记可达点为 \(vis1_i\)
  • 反向建图, 从 \(n\) 出发染色,标记可达点为 \(visn_i\)

可以到的点就是两次都被标记的。不用并查集可能是因为是有向图


建图完成后, \(spfa\) 跑最短路
无解情况 :

  • \(vis1_n = 0\), 没有路径
  • 不等式有负环

答案: 边权是 \(dis_v - dis_u\)

差分约束结论3

给定每\(x_i\)的限制范围,要求\(\sum x_i\) 的最小值,通过差分约束来解决每一个位置的最小值,求 和 的最小值

CF67A Partial Teacher

最小值, 跑最长路

  • = 连两条\(i\)\(i - 1\) 的边
  • L \(i\)\(i-1\)\(1\) 的边
  • R \(i-1\)\(i\) 的为 \(1\) 的边
    正常,\(spfa\) 就可以
    答案是 \(dis\)

另一种做法
先不管 = 号
因为有解, 所以没有环
相当于只一个 \(DAG\)
建边(小的位置往大的连一条边)后拓扑跑
对于一个点的每一条入边带来的权+1,比它大,又尽可能小


等号就把相等的一坨染成一个颜色,当成一个点去做就行了

posted @ 2025-12-21 13:34  wmq2012  阅读(2)  评论(0)    收藏  举报