Commit 49daba22 authored by sshwy's avatar sshwy
Browse files

min-cost and max-flow

parent 11ef2b1d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -462,7 +462,7 @@ HLPP 的上界为 $O(n^2\sqrt m)$ ,但在使用时卡得比较紧;我们可

HLPP 推送的条件是 $h(u)=h(v)+1$ ,而如果在算法的某一时刻, $h(u)=t$ 的结点个数为 $0$ ,那么对于 $h(u)>t$ 的结点就永远无法推送超额流到 $t$ ,因此只能送回 $s$ ,那么我们就在这时直接让他们的高度变成 $n+1$ ,以尽快推送回 $s$ ,减少重贴标签的操作。

???+ "LuoguP4722【模板】最大流 加强版/预流推进"
??? "LuoguP4722【模板】最大流 加强版/预流推进"
    
    ```cpp
    #include <cstdio>
+47 −53
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@

相当于把 $w(u,v)$ 作为边权,在残存网络上求最短路

#### 核心代码
???+ "核心代码"
    
    ```cpp
    struct qxx {
@@ -72,19 +72,15 @@ void update() {

## 类 Dinic 算法

我们可以在 $\text{Dinic}$ 算法的基础上进行改进,把 $\text{BFS}$ 求分层图改为用 $\text{SPFA}$ (由于有负权边,所以不能直接用 $\text{Dijkstra}$ )来求一条单位费用之和最小的路径,也就是把 $w(u,v)$ 当做边权然后在残量网络上求最短路,当然在 $\text{DFS}$ 中也要略作修改。这样就可以求得网络流图的 **最小费用最大流** 了。
我们可以在 Dinic 算法的基础上进行改进,把 BFS 求分层图改为用 SPFA (由于有负权边,所以不能直接用 Dijkstra )来求一条单位费用之和最小的路径,也就是把 $w(u,v)$ 当做边权然后在残量网络上求最短路,当然在 DFS 中也要略作修改。这样就可以求得网络流图的 **最小费用最大流** 了。

如何建 **反向边** ?对于一条边 $(u,v,w,c)$ (其中 $w$ 和 $c$ 分别为容量和费用),我们建立正向边 $(u,v,w,c)$ 和反向边 $(v,u,0,-c)$ (其中 $-c$ 是使得从反向边经过时退回原来的费用)。

 **优化** :如果你是“关于 $\text{SPFA}$ ,它死了”言论的追随者,那么你可以使用 $\text{Primal-Dual}$ 原始对偶算法将 $\text{SPFA}$ 改成 $\text{Dijkstra}$
 **优化** :如果你是“关于 SPFA ,它死了”言论的追随者,那么你可以使用 Primal-Dual 原始对偶算法将 SPFA 改成 Dijkstra !

 **时间复杂度** :可以证明上界为 $O(nmf)$ ,其中 $f$ 表示流量。

* * *

### 代码

??? "最小费用最大流"
???+ "代码实现"
    ```cpp
    #include <algorithm>
    #include <cstdio>
@@ -154,8 +150,6 @@ void update() {
    }
    ```

* * *

## 习题

-    [「Luogu 3381」【模板】最小费用最大流](https://www.luogu.org/problemnew/show/P3381)