网络流学习笔记

网络流学习笔记

1、网络流概念和简介

我们称一个网络为一个有向有权图 G=(V,E)G=(V, E)。每条边有容量 c(u,v)c(u, v),即该边权值。一个网络中有两个特殊的点 sstt,即源点和汇点,其中 sV,tV,sts \in V, t \in V, s\neq t

可以理解为一个网络是一个水流。ss 点是大海,tt 点是蓄水池,其余的每个点是中间的点,不能储存水,只能进出。每条边是一条水管。

对于每一个网络,都会有若干个可行流。每个可行流里,对于 u,vVu, v \in Vf(u,v)f(u, v) 为该边的流量。若 (u,v)∉E(u, v) \not \in E(v,u)∉E(v, u) \not \in E,那么 f(u,v)=0f(u,v)=0。若 (u,v)∉E(u, v) \not \in E(v,u)E(v,u) \in E,即 (u,v)(u,v) 为原图边的某一条反向边,那么 f(u,v)=f(v,u)f(u, v) = -f(v,u),即原图边的相反数。

对于一个可行流,每个 f(u,v)f(u, v) 都满足容量限制和流量守恒。

  1. 容量限制:f(u,v)c(u,v)f(u, v) \leq c(u, v)。即流量不大于容量。

  2. 流量守恒:除 sstt 点外,每个点流入和流出的相等,即入边权值和等于出边权值和。即对于任意 uEu \in Eusu \neq sutu \neq t,都有 (p,u)Ef(p,u)=(u,p)Ef(u,p)\sum \limits_{(p,u)\in E} f(p,u) = \sum \limits_{(u,p) \in E} f(u,p)

若一个流是可行流,那么它的流量定义为 ss 点每单位时间流出或者 tt 每单位时间内流入的,即 (s,v)Ef(s,v)(v,s)Ef(v,s)\sum \limits_{(s,v) \in E} f(s,v) - \sum \limits_{(v,s) \in E} f(v,s)。通常 ss 不会有入边,即 (v,s)Ef(v,s)=0\sum \limits_{(v,s) \in E} f(v,s) = 0,但有时候可能会出现反向边。

2、最大流

最大流即最大可行流,对于一个网络 GG,其最大流为所有可行流中流量最大的流。

2.1 EK 算法

EK 算法是基于增广路的算法。

我们对于网络 GG 的一个可行流定义每条边的剩余容量 p(u,v)p(u,v)p(u,v)=c(u,v)f(u,v)p(u,v)=c(u,v)-f(u,v),即容量和流量的差。对于一个可行流,它有一个残留网络 GG^\primeGG^\prime 是原图中所有点和剩余容量 >0>0 的边组成的图,注意反向边也被算入其中。

G=(V,E)G^\prime = (V^\prime, E^\prime),其中 V=VV^\prime = VE={(u,v)E,p(u,v)>0}+{(v,u)E,p(u,v)>0}E^\prime = \{(u, v) \in E, p(u, v) > 0\} + \{(v,u) \in E, p(u,v)>0\}。通常我们认为反向边的容量 c(u,v)=0c(u,v)=0,反向边的流量 f(u,v)=f(v,u)f(u,v) = -f(v,u),即正向边的相反数。

增广路是指一条在残留网络上从源点 ss 到汇点 tt 的路径。

EK 算法是一种找增广路算法,每次在残留网络中找一条增广路并构建新的残留网络,找不到增广路时,就找到了一个最大流。注意要反向建边,这样可以反悔流量。因为每次找的增广路不一定是最优的。

使用 EK 算法实现 P3376

时间复杂度 O(nm2)O(nm^2),比较适用于稀疏图。

2.2 Dinic 算法

Dinic 算法也是基于增广路的算法。与 EK 算法不同,Dinic 算法在每个残留网络上不止会找一次增广路,而会多次增广,直到找不到新的路径时再重构残留网络,接着继续增广。

然而这样做复杂度并不会更优多少,Dinic 在每次对一个残留网络增广前,会把图分层。设 did_i 表示点 ii 的层数,那么 ds=0d_s=0did_iiiss 的最短路径,注意这里和边权无关,即 BFS 第一次搜到的就是最短路径。那么每次增广时,对于当前点 uu,为了避免环,每次我们只找 dv=du+1d_v = d_u+1 的边增广。

Dinic 算法通常还会有当前弧优化,即对于每一个残留网络,多次增广时,如果一条边增广过,那么对于这次的多次增广,这条边永远都不会重新增广。

使用 Dinic 算法实现 P3376。明显比 EK 快不少,复杂度 O(n2m)O(n^2m),适用于稠密图,稀疏图效率与 EK 差不多。比较推荐使用。

此外最大流还有基于增广路的 MPM,ISAP 和基于预留推进的 HLPP 等其他算法,但是 Dinic 通常不会被卡,其他算法暂时不介绍。

3、最小割

对于一个网络,定义一个割为一种点集划分方式。即将 VV 划分成两个点集 S,TS, T,使得 sS,tTs \in S, t \in T

定义一个割的容量 p(S,T)p(S, T) 为连接 SS 集合的某个点和 TT 集合的某个点的容量和。即 p(S,T)=uS,vTc(u,v)p(S,T) = \sum \limits_{u \in S, v \in T} c(u, v)。通常 p(S,T)p(S, T) 可以表示为 p(s,t)p(s, t),即将 sstt 两个点分进两个集合,其他节点随意分配。

最小割即容量最小的割。

接着考虑如何求最小割。

结论:一个网络的最大流等于这个网络的最小割。

对于任意流 FF 和任意割 S,TS, T,都有该可行流的流量 v(F)c(S,T)v(F) \leq c(S, T)

证明:可行流的流量 v(F)=(s,v)Ef(s,v)(u,s)Ef(u,s)=uS,vTf(u,v)uT,vSf(u,v)uS,vTf(u,v)c(S,T)v(F) = \sum\limits_{(s, v) \in E} f(s, v) - \sum\limits_{(u, s) \in E} f(u, s) = \sum \limits_{u \in S, v \in T} f(u, v) - \sum \limits_{u \in T, v \in S} f(u, v) \leq \sum \limits_{u \in S, v \in T} f(u, v) \leq c(S, T)

显然流量 \leq 容量。取等时容量最小,即 SS 不存在入边,也就是最大流时。

为什么流量 =S=S 出边权值和 S-S 如边权值和?一开始我也不太理解。SS 里,除了 ss,其余每个点满足流量守恒,所以入边和等于出边和,这些出边和一直拓展到 tt,但是注意到有些点尽管属于 SS,但是有来自 TT 的入边,那么这些流量就不是 ss 流出的,删去即可。

代码和最大流完全一致,不给出。

posted @   HappyBobb  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示