线性规划 1

推荐阅读:
https://www.cnblogs.com/frankkk/p/9179190.html
https://zhuanlan.zhihu.com/p/31644892
https://blunt-axe.gitee.io/2020/02/19/20200219-LP-Duality/

写到一半突然看到 dxm 的 2021 论文,所以也可以把这篇当作阅读随笔。当然两边的编排不是很一样,我可能之后会再看看那个。
写到最后突然看到 zxy 的 2016 论文,所以也可以把这篇当作阅读随笔。当然两边的编排不是很一样,我可能之后会再看看那个。

如果出现数学符号无法渲染的情况请多刷新几遍。

线性规划(\(\textbf{L}\text{inear} \textbf{ P}\text{rogramming}, \text{LP}\))是一类最优化问题,这类问题的约束条件和目标函数均是线性的。下文中将使用大量线性代数的语言。

一般地,我们使用斜粗体 \(\bm{a}\) 记向量,用斜体 \(a_i\) 表示 \(\bm a\) 中第 \(i\) 维的值。\(\bm a \ge \bm b\) 当且仅当 \(\forall i,\ a_i \ge b_i\)。记 \(\mathbb R^n\) 表示 \(n\) 维实向量组成的空间。

1 形式

首先介绍线性规划的标准形式。

\(\text{定义 1}\)(线性规划的标准形式)

\(A\in \mathbb R^{n\times m}, \bm b \in \mathbb R^n, \bm c\in \mathbb R^m\)。以下问题被称作线性规划的标准形式

\[\begin{aligned} \max_{\bm x} & \quad \bm c^{\mathsf T} \bm x \\ \text{s.t.} & \quad A\bm x\le \bm b, \ \bm x \ge \bm 0 \end{aligned}\]

需要优化的目标函数为 \(\bm c^{\mathsf T} \bm x\),其对应的解为 \(\bm x\)。约束条件为 \(A\bm x\le \bm b, \ \bm x \ge \bm 0\)。我们将满足约束条件的解称作可行解,其全体称作可行域。可行解中满足最大化目标函数的解称作最优解 \(\bm x^*\),此时目标函数的值称为此线性规划问题的值。习惯上一个线性规划问题的代号同样指代该问题的值。

所有线性规划问题都可以被表示为标准形式。同时,线性规划有一种松弛形式,其利于几何分析与施单纯形法求解。这时我们需要满足 \(\bm b\ge \bm 0\)

我们可以发现,\(\bm b - A\bm x = \bm x'\) 的解定满足 \(\bm x' \ge \bm 0\)。因此可以等价地将标准形改写成

\[\begin{aligned} \max_{\bm x} & \quad \bm c^{\mathsf T} \bm x \\ \text{s.t.} & \quad \left[A \ \ I_m \right] \left[\begin{aligned} \bm x& \\ \bm x&' \end{aligned}\right] = \bm b, \ \bm x, \bm x' \ge \bm 0 \end{aligned}\]

随后可以通过适当地变号(\(b_i < 0\Rightarrow\)\(i\) 行变号)使得定满足 \(\bm b \ge \bm 0\)。因此有与标准形式等价的松弛形式

\(\text{定义 2}\)(线性规划的松弛形式)

\[\begin{aligned} \max_{\bm x} & \quad \bm c^{\mathsf T} \bm x \\ \text{s.t.} & \quad A\bm x = \bm b, \ \bm x \ge \bm 0 \end{aligned}\]

这样可以轻易地确定一组可行解,即 \(\bm x = \bm 0, \bm x' = \bm b\)

基本形式就介绍到这里,接下来我们考虑如何求解线性规划问题。

2 求解

2.1 基础内容讨论

考虑 \(A\) 是一个 \(n\times m\) 的矩阵,\(\text{rank}(A) = m\)。我们将 \(A\) 中的列向量重新排序,以期得到更好的性质。具体地,我们提取 \(A\)\(m\) 个线性无关的列向量组成一个方阵 \(B\),将剩余的向量组成一个 \((n - m) \times m\) 的矩阵 \(D\)\(A\) 可以被写作分块矩阵 \(\left[B\ \ D\right]\) 的形式。我们称 \(B\) 为一个基,其中的列向量称作基本列向量。

矩阵 \(B\) 非奇异,因此 \(A\bm x = \bm b\) 的一组解 \(\bm x\) 的前 \(m\) 个元素对应了 \(B^{-1}\bm b\),其余元素为 \(0\)。我们称这样的 \(\bm x\)\(A\bm x = \bm b\) 的一组基解,其元素 \(x_i\) 称作基变量。可以发现基解的数量最多是 \(C_n^m\) 个。满足 \(\bm x \ge \bm 0\) 的解被称作基可行解。

此时有 \(B\bm x_B = \bm b\)。由于矩阵 \(B\) 非奇异,\(\bm x_B = B^{-1} \bm b\)。此时若将 \(\bm c\)\(B-D\) 分块为 \(\bm c = [\bm c_B \ \ \bm c_D]\),目标函数值即为 \(z = \bm c_B^{\mathsf T} B^{-1} \bm b\)

可以发现,可行域一定对应 \(\mathbb R^m\) 内的一个凸集(或空集),且每个基可行解总对应这个凸集的一个角点。感性理解
同时,最优解一定对应着一个基可行解。

我们求解答案的算法可以首先确定一个角点,随后一步步转移到最优解对应的角点。这就是单纯形法。

2.2 单纯形法

总的来说,单纯形法分为三个部分,我们需要回答以下问题:

  1. 如何从一个角点转移到相邻的角点?
  2. 如何确定该转移到哪个角点?
  3. 什么时候才能停止转移?即,如何判断当前解是最优解?

假设当前的约束矩阵 \(A = \left[B\ \ D\right]\),已经得到了一组基可行解 \(\bm x_0 = \left[\begin{aligned} \bm x&_B \\ \bm x&_D \end{aligned}\right]\)\(\bm x_B\) 对应的一组基变量为 \(\{x_i\}\),基本列向量为 \(\{\bm a_i\}\)
由于 \(B\) 非奇异,其定能表出任意 \(m\) 大小的向量。从 \(D\) 中取出一个向量 \(\bm a_e\),则这个列向量可以由 \(\{\bm a_i\}\) 的线性组合表出。即 \(\exists \bm\lambda = (\lambda_1, \lambda_2, \dots, \lambda_m)^{\mathsf T},\ \sum_{i=1}^m \lambda_ia_i = B\bm\lambda = \bm a_e\)。我们令

\[\mu = \min_{x_i > 0, \bm a_i \in B} \frac {x_i}{\lambda_i}\quad l = \mathop{\text{arg min}}_{x_i > 0, \bm a_i \in B} \frac {x_i}{\lambda_i} \]

我们称 \(x_l\) 为出基变量,\(x_e\) 为入基变量;对应的列向量被称作出/入基向量。我们将使用所求值构造新解。

我们令 \(\bm x' = \bm x - \mu \bm \lambda\) 为基 \(B' = B / \{\bm a_l\} \cup \{\bm a_e\}\) 对应的一组解,其中 \(\bm \lambda = (\lambda_1, \lambda_2, \dots, \lambda_m, 0, \dots, -1, \dots, 0)^{\mathsf T}\)\(-1\) 是入基变量的系数)。由于 \(A\bm x' = A(\bm x - \mu \bm \lambda) = A\bm x - \mu (A \bm \lambda)\),且 \(A\bm \lambda = \sum_{i=1}^m \lambda_i \bm a_i - \bm a_e = \bm 0\),因此 \(\bm x'\) 为一组新的可行解。

但是问题又来了,该如何选择入基向量才能使得答案变化最大呢?

若现在的一组解是 \(\bm x\),目标函数的值为 \(f = \bm c_B^{\mathsf T} B^{-1} \bm b\)。我们新选取的可行解是 \(\bm x'\),其同样满足 \(B \bm x'_B + D \bm x'_D = \bm b\),即 \(\bm x'_B = B^{-1}(\bm b - D \bm x'_D)\)。则新可行解

\[\begin{aligned} f' & = \bm c_B^{\mathsf T}\bm x'_B + \bm c_D^{\mathsf T} \bm x'_D \\ & = \bm c_B^{\mathsf T}B^{-1}(\bm b - D \bm x'_D) + \bm c_D^{\mathsf T} \bm x'_D \\ & = f - \left(\bm c_B^{\mathsf T}B^{-1}D - c_D^{\mathsf T}\right)\bm x'_D \end{aligned}\]

我们现在只需要看两解的差值即可。

\[\begin{aligned} \Delta f & = \left(\bm c_B^{\mathsf T}B^{-1}D - c_D^{\mathsf T}\right)\bm x'_D \\ & = \sum_{i=m+1}^n (c_B^{\mathsf T}B^{-1} \bm a_i - c_i) x'_i \end{aligned}\]

\(z_i = c_B^{\mathsf T}B^{-1} \bm a_i\)。能发现,选择一个非基变量 \(x_i\),会让结果变化 \((z_i - c_i) x'_i\)\(x'_i > 0\),这时若有 \(z_i - c_i < 0\),就能确定一个更优的解 \(\bm x'\)。我们希望每次选择的值是最优的,因此每次都选择 \(x_k \text{ s.t. } k = \mathop{\text{arg max}}_i (z_i - c_i)\)

我们将 \(z_i - c_i\) 称作判别数。选择新角点的关键是首先求出非基变量的判别数,从其中选取最小的负值,其对应的非基变量就是新的入基变量。

这也自然地导出了最优解:当一个角点处所有判别数均非负时,这个角点无法转移到更大的值处,因此其取得了最大值。

讲到这里,我们就能发现先前提到的松弛形式的意义了。松弛形式引入了数个人工变量 \(\bm x'\),从而能快速构造出一组初始解,方便单纯形法求解。

我们还能发现,若原线性规划问题有解 \(\bm x\),对于松弛形式,只有当 \(\bm x' = \bm 0\) 时才能得到最优解。

有时可行域是无界的,这时可能取到一个无穷大的解,此时称该线性规划问题的解为无界解。由于在实际问题中不可能取到无穷大,因此无界解通常表明问题的形式有误。
在单纯形法中,无界解等价于 \(\bm \lambda < \bm 0\)

关于单纯形法的复杂度,可以参阅以下两篇论文:

  1. Smoothed Analysis of Algorithms: Why the Simplex Algorithm Usually Takes Polynomial Time?, Daniel A. Spielman, Shang-Hua Teng, 2001
  2. A Randomized Polynomial-Time Simplex Algorithm for Linear Programming, Jonathan A. Kelner, Daniel A. Spielman, 2006

可以相信在绝大多数情况下,单纯形算法都可以处理 \(10^3\sim 10^4\) 的数据。

只应用单纯形法有时无法解决问题,我们需要借助其他方法将问题转化。

3 对偶法

一个常用的方法是对偶。

3.1 对偶的基础应用

首先给出对偶问题的定义:

\(\text{定义 3}\)(线性规划的对偶)

给出一个线性规划的如定义 \(1\) 的标准形式,其称为原问题(下文称 \(P, \textbf{P}\text{rimal}\)\(\text{LP}\))。以下问题则称为 \(P\) 的对偶(下文称 \(D, \textbf{D}\text{ual}\)\(P^*\)):

\[\begin{aligned} \min_{\bm y} & \quad \bm b^{\mathsf T} \bm y \\ \text{s.t.}&\quad A^{\mathsf T}\bm y\ge \bm c, \bm y \ge\bm 0 \end{aligned}\]

容易验证 \((P^*)^* = P\)。因此一个线性规划标准形的对偶也是标准形。

\(\textbf{例 1. }\) 写出一般图最大匹配对应的 \(\text{LP}\) 形式,以及 \(\text{LP}^*\)。说明 \(\text{LP}^*\) 的意义。

设图 \(G = \{V, E\}\) 的关联矩阵 \(M\in \mathbb F_2^{n\times m}\)。令 \(\bm x\in \mathbb F_2^{m}\) 表示取边集 \(X\in E\) 函数(即 \(\bm 1_{e\in X}\))。注意 \(M\) 不是邻接矩阵。
考虑约束 \(M\bm x \le \bm 1\)。这表示 \(\bm x\) 取到的边集同 \(M\) 中每个点至多有一次邻接,即一个匹配。目标函数可以写作 \(|X| = \bm 1 ^{\mathsf T} \bm x\),也就是最大匹配数。有标准形式

\[\begin{aligned} \max_{\bm x} & \quad \bm 1 ^{\mathsf T} \bm x\\ \text{s.t.} & \quad M\bm x \le \bm 1, \ \bm x \ge \bm 0 \end{aligned}\]

带权图则可以将 \(\bm 1\) 转化为 \(\bm w\)

同样地,我们可以写出对偶

\[\begin{aligned} \min_{\bm y} & \quad \bm 1 ^{\mathsf T} \bm y\\ \text{s.t.} & \quad M ^{\mathsf T}\bm y \ge \bm 1, \ \bm y \ge \bm 0 \end{aligned}\]

这时 \(\bm y \in \mathbb F_2^{n}\) 表示了取点集 \(Y\in V\) 函数(即 \(\bm 1_{u\in V}\))。此时约束表示了 \(E\) 中每一条边都至少与 \(Y\) 中一个顶点相邻,最小化目标函数即找到最小的满足条件的点集大小。
这使我们想到了点覆盖。可以发现,最大匹配的对偶问题是最小点覆盖问题。

3.2 对偶性

在上面的问题中,我们发现自变量的取值范围仅为整数。这比一般线性规划的要求高。如果线性规划问题中 \(A, \bm x, \bm b\) 的元素都是整数,则我们称该问题为整数线性规划(\(\text{ILP}, \textbf{I}\text{nteger }\textbf{L}\text{inear }\textbf{P}\text{rogramming}\))。

需要注意的是,求解一般的整数线性规划问题是 \(\text{NP-Hard}\) 问题。对于特殊问题,如二分图的匹配,最优解一定对应着一组整数解,因此可以视作普通线性规划求解。
具体地,\(A\bm x = \bm b\) 的所有基本解均为整数向量当且仅当 \(A\) 为一全幺模矩阵。因此当约束矩阵是全幺模矩阵时,整数线性规划可以与普通线性规划同方式求解。

对于对偶问题,有以下定理。

\(\textbf{定理 1}\)(弱对偶性)

设线性规划的原问题和对偶如定义 \(1,3\) 形式,记为 \(P, D\)\(P\) 的值不大于 \(D\) 的值。特别地,如果 \(\bm x, \bm y\) 分别为 \(P,D\) 的可行解,且满足 \(\bm c^{\mathsf T} \bm x = \bm b^{\mathsf T} \bm y\),则 \(\bm x, \bm y\) 分别为 \(P,D\) 的最优解。

证明:

\[\bm c^{\mathsf T}\bm x \le \bm y^{\mathsf T} A \bm x \le \bm y^{\mathsf T} \bm b = \bm b^{\mathsf T} \bm y \]

由这个可以引出一般图最大匹配不大于最小点覆盖。可以证明在二分图中最大匹配等于最小点覆盖,而这需要应用强对偶性。证明见此

\(\textbf{定理 2}\)(强对偶性)

设线性规划的原问题和对偶如定义 \(1,3\) 形式,记为 \(P, D\)。下面的叙述有且仅有一个成立:

  1. \(P, D\) 均有最优解,且 \(P = D\)
  2. \(P\) 有可行解,\(D\) 无可行解,且 \(P\) 的目标函数在约束条件下无界。
  3. \(D\) 有可行解,\(P\) 无可行解,且 \(D\) 的目标函数在约束条件下无界。
  4. \(P, D\) 均无可行解。

我们若想计算原问题的最优解,很多情况下就可以转化为计算对偶问题的最优解。

\(\textbf{例 2.}\) 求解带权二分图最大权匹配。

我们设左右各 \(n\) 个点的二分图 \(G\) 的关联矩阵为 \(M\in \mathbb F_2^{2n\times m}\),边权为 \(\bm w\in \mathbb R_+^{m}\)。我们需要找出一个完美匹配使得边集中包含的边权和最大。

仍然考虑 \(\bm x\) 代表取边集函数。写出 \(P\)

\[\begin{aligned} \max_{\bm x} & \quad \bm w ^{\mathsf T} \bm x\\ \text{s.t.} & \quad M\bm x \le \bm 1, \ \bm x \ge \bm 0 \end{aligned}\]

转对偶:

\[\begin{aligned} \min_{\bm y} & \quad \bm 1 ^{\mathsf T} \bm y\\ \text{s.t.} & \quad M\bm y \ge \bm w, \ \bm y \ge \bm 0 \end{aligned}\]

容易发现这就是 KM 算法所模拟的过程,其最终也最小化了顶标和。因此应用 KM 算法即可。

3.3 流模型的应用

\(\textbf{例 3.}\) 浅析最大费用循环流模型。

首先我们需要解决一个问题。假设题目信息被抽象为了一个线性规划问题,但是其要求并不只是各维满足 \(\le\),还要求在特定维上满足 \(=\)。如何解决?

假设这一维描述为 \(\bm a_i x_i = b_i\)。则我们可以将其视为 \(\bm a_i x_i \le b_i\ \land\ -\bm a_i x_i \le - b_i\)。假设这两个限制对偶后对应的变量是 \(y_1, y_2\),则我们需要最小化 \(b_i(y_2 - y_1)\)。虽然有限制 \(\bm y \ge \bm 0\),但是可以发现 \(y_2 - y_1\) 不一定 \(\ge 0\)。因此不拆开的限制对偶后对应的变量 \(y\) 是没有限制的,其 \(\in \mathbb R\)

同样的,如果原问题中存在 \(\in \mathbb R\) 的变量,对偶后对应的限制就应当取等。

然后定义最大费用循环流模型:循环流是无源汇的流,满足每个节点流量守恒。给定一张流网络,容量为 \(\{c_{i, j}\}\),费用为 \(\{w_{i, j}\}\)。求一个循环流 \(f\),最大化 \(\sum_{(u, v)} f_{u, v} \times w_{u, v}\)

最大费用循环流可以通过网络流的方式求解,具体看无源汇最大费用可行流。

问题写作线性规划形式即为

\[\begin{aligned} \max_{f} & \quad \sum_{(u, v)} f_{u, v} \times w_{u, v}\\ \text{s.t.} & \quad \forall(u, v), \ f_{u, v} \le c_{u,v} \\ & \quad \forall(u, v), \ f_{u, v} = f_{v, u} \\ & \quad \forall(u, v), \ f_{u, v} \ge 0 \end{aligned}\]

转对偶。假设第一个限制条件对应的变量为 \(d_{u,v}\),第二个限制条件对应的变量为 \(y_{u,v}\),有

\[\begin{aligned} \min_{d, y} & \quad \sum_{(u, v)} d_{u,v} \times c_{u,v} \\ \text{s.t.} & \quad \forall(u, v), \ d_{u,v} + y_{u,v} \ge w_{u, v} \\ & \quad \forall(u, v), \ d_{u,v}\ge 0 \end{aligned}\]

容易发现 \(d_{u,v} = \max(0, w_{u, v} - y_{u,v})\) 时最优。因此最大费用循环流的目标就是最小化

\[\sum_{(u, v)} \max\left(0, w_{u, v} - y_{u,v}\right) \times c_{u,v} \]

因此我们可以将一个问题转化为最小化上式,随后利用网络流求解。

\(\textbf{例 4.}\) 浅析最小费用流模型。

给定一张流网络,容量为 \(\{c_{i, j}\}\),费用为 \(\{w_{i, j}\}\)\(b_u\)\(u\) 点的流出量(出流量 \(-\) 入流量 \(=\) \(b_u\))。求一个流 \(f\),最小化 \(\sum_{(u, v)} f_{u, v} \times w_{u, v}\)

\[\begin{aligned} \min_{f} & \quad \sum_{(u, v)} f_{u, v} \times w_{u, v}\\ \text{s.t.} & \quad \forall(u, v), \ f_{u, v} \le c_{u,v} \\ & \quad \forall u, \ \sum_{v} f_{v, u} - \sum_{v} f_{u, v} = - b_u \\ & \quad \forall(u, v), \ f_{u, v} \ge 0 \end{aligned}\]

\(d_{u,v}\)\(- f\) 的变量,\(y_u\) 为需求变量。转对偶有

\[\begin{aligned} \max_{d, y} & \quad \sum_{u} -b_u y_u - \sum_{(u, v)} d_{u, v} c_{u,v} \\ \text{s.t.} & \quad \forall(u, v), \ y_v - y_u - d_{u, v} \le w_{u, v} \\ & \quad \forall(u, v), \ d_{u,v}\ge 0 \end{aligned}\]

也就是说我们需要 \(y_v\)\(\sum_{w} f_{v, w} - \sum_{w} f_{w,v}\)\(-y_u\)\(\sum_{v} f_{u,v} - \sum_{v} f_{v, u}\)\(d_{u,v}\)\(-f_{u,v}\)

整理可得我们需要最小化

\[\sum_{u} b_u y_u + \sum_{(u, v)} c_{u,v} \times \max(0, y_v - y_u - w_{u, v}) \]

这样遇到类似于最小化这类式子的题就可以采用单纯形法做了。

4 例题

[ZJOI2013] 防守战线

战线可以看作一个长度为 \(n\) 的序列,现在需要在这个序列上建塔来防守敌兵,在序列第 \(i\) 号位置上建一座塔有 \(c_i\) 的花费,且一个位置可以建任意多的塔,费用累加计算。有 \(m\) 个区间 \([l_1, r_1], [l_2, r_2], \dots , [l_m, r_m]\),在第 \(i\) 个区间的范围内要建至少 \(d_i\) 座塔。求最少花费。

\(1\le n\le 1000, 1\le m\le 10000\)

考虑设 \(\bm x\) 为塔数量的向量,\(\bm c\) 为花费向量,\(\bm d\) 为建塔数量向量。构造矩阵 \(A\) 满足 \(A_{i, j} = [l_i \le j \le r_i]\)。注意到 \(A\) 是全幺模矩阵,因此可以施单纯形法求解。

立即写出线性规划形式:

\[\begin{aligned} \min_{\bm x} & \quad \bm c^{\mathsf T} \bm x \\ \text{s.t.} & \quad A\bm x\ge \bm d, \ \bm x \ge \bm 0 \end{aligned}\]

转对偶便于求解。

\[\begin{aligned} \max_{\bm y} & \quad \bm d^{\mathsf T} \bm y \\ \text{s.t.} & \quad A^{\mathsf T}\bm y\le \bm c, \ \bm y \ge \bm 0 \end{aligned}\]

直接做即可。

单纯形法

怎么和我上面讲的单纯形法实现不一样?

#include <bits/stdc++.h>
using namespace std; 
#define rep(i,s,t) for (register int i = (s), i##_ = (t) + 1; i < i##_; ++ i)
#define pre(i,s,t) for (register int i = (s), i##_ = (t) - 1; i > i##_; -- i)
const int inf = 1e9;
const double eps = 1e-9;
int n, m, l, r;

namespace Simp {
	const int N = 1e3 + 5, M = 1e4 + 5;

	double A[N][M], c[N], d[M], res;

	void pivot(int e, int l) {
		double t = A[l][e];
		c[l] /= A[l][e], t = A[l][e], A[l][e] = 1;
		rep(i,1,m) if (i != e) A[l][i] /= t;
		rep(i,1,n) if (i != l and fabs(A[i][e]) > eps) {
			c[i] -= A[i][e] * c[l];
			rep(p,1,m) if (p != e) A[i][p] -= A[i][e] * A[l][p];
			A[i][e] = -A[i][e] * A[l][e];
		} res += d[e] * c[l];
		rep(i,1,m) if (i != e) d[i] -= d[e] * A[l][i];
		d[e] = -d[e] * A[l][e];
	}

	double simplex() {
		int j, k;
		while (1) {
			double mn = inf; k = 0;
			for (j = 1; j <= m; ++ j) if (d[j] > eps) break;
			if (j > m) return res;
			rep(i,1,n) if (A[i][j] > eps and mn > c[i] / A[i][j])
				k = i, mn = c[i] / A[i][j];
			if (mn >= inf) return inf;
			pivot(j, k);
		} return res;
	}

	int calc() { return (int)(simplex() + 0.5); }
} // namespace Simplex_Method

signed main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m;
	rep(i,1,n) cin >> Simp::c[i];
	rep(i,1,m) {
		cin >> l >> r >> Simp::d[i];
		rep(j,l,r) Simp::A[j][i] = 1;
	} cout << Simp::calc() << '\n';
}

本题的另一种做法是应用最小费用流模型,将问题转化成最小费用最大流求解。

对建塔数作前缀和得到 \(\{p_i\}\),得到线性规划模型

\[\begin{aligned} \min_{\bm x} & \quad \sum_{i=1}^n (c_i - c_{i - 1}) p_i \\ \text{s.t.} & \quad p_{i + 1} - p_{i} \ge 0\\ & \quad p_{r_i} - p_{l_i - 1} \ge d_i \end{aligned}\]

转化后面两个条件为 \(p_{i} - p_{i + 1} \le 0,\ d_i - p_{r_i} + p_{l_i - 1} \le 0\)。可以通过与 \(0\)\(\max\) 约束取值范围。不难写出等价关系式

\[\sum_{v}p_v (c_v - c_{v + 1}) + \sum_{i} \infty\times \max(0, p_i - p_{i + 1}) + \sum_{i} \infty \times \max(0, d_i - p_{r_i} + p_{l_i - 1}) \]

这就转化成最小费用流模型了。构图方式较明显。\(i + 1\to i\)\((\infty, 0)\) 的边,\(r\to l - 1\)\((\infty, -d_i)\) 的边,源点向 \(c_v - c_{v + 1} > 0\) 的点连 \((c_v - c_{v + 1}, 0)\) 的边,\(c_v - c_{v + 1} < 0\) 的点向汇点连 \((c_{v + 1} - c_v, 0)\) 的边。最终费用取负值即可。

值得注意的是,该做法的实际复杂度远劣于单纯形法,在实际测试中得到了 70pts

这也使得 UOJ487 中单纯形法变成了良好的优化,即网络单纯形法。可能在明天闲话里会谈到。

接 LP 2

posted @ 2022-12-27 17:54  joke3579  阅读(474)  评论(0编辑  收藏  举报