网络流初级复习

前言#

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

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

前置知识#

  • 初步了解网络

  • 会写 EK 板子

  • 会写 Dinic 板子

网络流的三个性质#

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

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

  • uS,T,  vf(u,v)=0

EK 算法证明#

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

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

  • 时间复杂度:EK 算法时间复杂度为 O(nm2)

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

最小割#

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

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

Hall 定理#

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

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

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

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

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

最小割树#

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

算法流程如下:

  • 选择两个点 s,tS

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

  • 最后拆成两个点集 Vs,Vt,分别递归 solve(Vs),solve(Vt)

建模分析#

  • 匹配模型

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

  • 拆点技巧

把一个点 u 拆成入点和出点 uin,uout,一条本来连接 (u,v) 的边变为连接 (uout,vin)

例题:P2774 方格取数加强版

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

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

例题:CF103E Buying Sets

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

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

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

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

例题:P3227 [HNOI2013]切糕

每个二维点看做变量 xi,j,那么相邻格子的变量取值绝对值之差 dxi,jk 的代价为 v[k,i,j]

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

我们需要算上限制,对于两个变量 x1,x2,我们在 x1Val 的边的前驱驱向 x2Vald 的前驱连边,那么 x1,x2Val,<Vald 时还需要割边,于是构造出了不合法的判断方法。

例题:ARC107F Sum of Abs

每个点有三种情况:删除、收益为 bi、收益为 bi

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

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

但是有个限制:同一联通快内的点必须统一取 bibi。这跟上题很类似,有连边的两个点不能取不同的两个收益。对于有连边没删除的边 (u,v),令 uoutvin 连一条容量为 inf 的边,即可保证 u,v 不能同时取 bu,bv

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

出处:https://www.cnblogs.com/Sktn0089/p/17609815.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   Lgx_Q  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示