Loading

网络流初级复习

前言

本人初识网络流后,基本上没什么接触,这两天专门训练,加深了对网络流得巩固。

本文只基于初级巩固介绍网络流算法。

前置知识

  • 初步了解网络

  • 会写 EK 板子

  • 会写 Dinic 板子

网络流的三个性质

  • \(f(u,v)=-f(v,u)\)

  • \(f(u,v)\le c(u,v)\)

  • \(u\not= S,T,\space\space \sum\limits_v f(u,v)=0\)

EK 算法证明

  • 残量调整定理:原图上的任何一种合法流,都可以从残量网络上调整得到。

证明:对于 \(f(u,v)=w\),显然有 \(f(v,u)=-w\),此时边 \((v,u)\) 剩余容量为 \(w\)。不超过容量限制的调整,相当于在原图上增加流量,也可以退回流量。

  • 时间复杂度:EK 算法时间复杂度为 \(O(nm^2)\)

证明:每一次 \(\text{Bfs}\) 需要 \(O(m)\),最短路的长度有只会单调上升,最多 \(O(n)\),种类数为 \(O(m)\),所以时间复杂度为 \(O(nm^2)\)

最小割

  • 最大流 - 最小割定理:最小割等于最大流。

证明:设最小割为 \(\text{mincut}\),最大流为 \(\text{maxflow}\)。首先 \(\text{mincut}\ge\text{maxflow}\),对于最小割的边集,令这些边最大流满流,显然不可能存在其他增广路径。我们只需要在最大流方案中选择一种方案,满足最小割等于最大流即可。

Hall 定理

一张二分图,分别有 \(n,m(n\le m)\) 个点。有两个条件与结论:

  • \(N(S)\) 表示左部点集合 \(S\) 中的点连的右部点的并集。二分图存在完美匹配,当且仅当对于任意一个 \(n\) 个点的子集 \(S\),满足 \(|N(S)|\ge |S|\),。

证明:必要性:若存在 \(S\) 满足 \(|N(S)|<|S|\),显然不可能存在完美匹配。充分性:考虑数学归纳法,当 \(n=1\) 时显然成立。对于 \(n\) 个点,假设已知对 \(1...n-1\) 成立。若任意一个集合 \(S\) 都满足 \(|N(S)|>|S|\),我们将点 \(n\) 随便和一个右部点匹配,不难发现剩下 \(n-1\) 点的任意一个集合 \(S'\) 仍然满足 \(|N(S')|\ge|S'|\);否则,选择一个 \(S\) 满足 \(|N(S)|=|S|\),根据假设,\(S\) 内的点存在完美匹配。考虑对剩下点的更新,发现对于一个集合 \(S_1=S_2+S_3\)(其中 \(S_2,S_3\) 分别为剩下点的集合和 \(S\) 的子集),已知 \(|N(S_1)|\ge|S_1|\),减去 \(S_3\),对应的右部点数量也减去 \(|S_3|\),那么 \(|N'(S_2)|=|N(S_1)|-|S_3|\ge|S_1|-|S_3|\ge|S_2|\),条件仍然成立,根据假设,剩下的点也存在完美匹配。

  • 推广:二分图的最大匹配数量为 \(\min\limits_{S}\{n-|S|+|N(S)|\}\)

证明:考虑建立网络流模型,跑最小割,上式其实就是最小割。

最小割树

\(\text{solve}(S)\) 表示对点集 \(S\) 建立最小割树。

算法流程如下:

  • 选择两个点 \(s,t\in S\)

  • 在原图上跑 \(s,t\) 的最小割。

  • 最后拆成两个点集 \(V_s,V_t\),分别递归 \(\text{solve}(V_s),\text{solve}(V_t)\)

建模分析

  • 匹配模型

如二分图:建立源点连接左部点,建立汇点连接右部点。

  • 拆点技巧

把一个点 \(u\) 拆成入点和出点 \(u_{in},u_{out}\),一条本来连接 \((u,v)\) 的边变为连接 \((u_{out},v_{in})\)

例题:P2774 方格取数加强版

每个方格拆点,入点和出点连一条容量为 \(1\),费用为对应权值的边,再连一条容量为 \(\inf\),费用为 \(0\) 的边。上面的格子向下面的格子连容量为\(\inf\),费用为 \(0\) 的边,左边对右边同理。然后跑最大费用最大流即可。

  • 最小割处理“一面对多面”

例题:CF103E Buying Sets

源点向每个元素连边,每个元素向对应子集连边,子集向汇点连边。

不考虑权值,每条边容量为 \(1\)(除了元素向子集连的边为 \(\inf\)),跑最小割,不难发现对于表子集的点,要么割去向汇点连的点,要么割去所有子集元素与源点的连边。所以割去源点连接元素表示选择这个元素,割去子集向汇点连的边表示放弃这个子集的收益。

不难发现这样的图最小割为 \(n\)。为了使得割去的边数保持为 \(n\) 而又能考虑到权值收益,先把所有权值取相反数,然后作为子集连向汇点的边的容量,之后把所有边容量加上 \(\inf\)

  • 最小割处理 变量取值收益最小/大化+取值(差)限制

例题:P3227 [HNOI2013]切糕

每个二维点看做变量 \(x_{i,j}\),那么相邻格子的变量取值绝对值之差 \(\le d\)\(x_{i,j}\)\(k\) 的代价为 \(v[k,i,j]\)

对于每个变量,在源点和汇点之间连一条链,链上边的容量依次是 \(v[1...r,i,j]\),不难发现,跑一遍最小割即可得到每个变量取值代价最小的代价和。

我们需要算上限制,对于两个变量 \(x_1,x_2\),我们在 \(x_1\)\(Val\) 的边的前驱驱向 \(x_2\)\(Val-d\) 的前驱连边,那么 \(x_1,x_2\)\(\ge Val,<Val-d\) 时还需要割边,于是构造出了不合法的判断方法。

例题:ARC107F Sum of Abs

每个点有三种情况:删除、收益为 \(b_i\)、收益为 \(-b_i\)

有删除操作,考虑拆点,把每个点拆成入点和出点,入点和出点连一条容量为 \(a_i\) 的边。

类似于最小割的经典二选一问题,我们令源点向入点连一条容量为 \(b_i\) 的边,出点向汇点连一条容量为 \(-b_i\) 的点。

但是有个限制:同一联通快内的点必须统一取 \(b_i\)\(-b_i\)。这跟上题很类似,有连边的两个点不能取不同的两个收益。对于有连边没删除的边 \((u,v)\),令 \(u_{out}\)\(v_{in}\) 连一条容量为 \(\inf\) 的边,即可保证 \(u,v\) 不能同时取 \(-b_u,b_v\)

容量可能有负数,让所有都加 \(\inf\) 即可。

posted @ 2023-08-06 19:25  Lgx_Q  阅读(26)  评论(0编辑  收藏  举报