网络流学习笔记
1、网络流概念和简介
我们称一个网络为一个有向有权图 G=(V,E)。每条边有容量 c(u,v),即该边权值。一个网络中有两个特殊的点 s 和 t,即源点和汇点,其中 s∈V,t∈V,s=t。
可以理解为一个网络是一个水流。s 点是大海,t 点是蓄水池,其余的每个点是中间的点,不能储存水,只能进出。每条边是一条水管。
对于每一个网络,都会有若干个可行流。每个可行流里,对于 u,v∈V,f(u,v) 为该边的流量。若 (u,v)∈E 且 (v,u)∈E,那么 f(u,v)=0。若 (u,v)∈E 但 (v,u)∈E,即 (u,v) 为原图边的某一条反向边,那么 f(u,v)=−f(v,u),即原图边的相反数。
对于一个可行流,每个 f(u,v) 都满足容量限制和流量守恒。
-
容量限制:f(u,v)≤c(u,v)。即流量不大于容量。
-
流量守恒:除 s 和 t 点外,每个点流入和流出的相等,即入边权值和等于出边权值和。即对于任意 u∈E,u=s,u=t,都有 (p,u)∈E∑f(p,u)=(u,p)∈E∑f(u,p)。
若一个流是可行流,那么它的流量定义为 s 点每单位时间流出或者 t 每单位时间内流入的,即 (s,v)∈E∑f(s,v)−(v,s)∈E∑f(v,s)。通常 s 不会有入边,即 (v,s)∈E∑f(v,s)=0,但有时候可能会出现反向边。
2、最大流
最大流即最大可行流,对于一个网络 G,其最大流为所有可行流中流量最大的流。
2.1 EK 算法
EK 算法是基于增广路的算法。
我们对于网络 G 的一个可行流定义每条边的剩余容量 p(u,v),p(u,v)=c(u,v)−f(u,v),即容量和流量的差。对于一个可行流,它有一个残留网络 G′。G′ 是原图中所有点和剩余容量 >0 的边组成的图,注意反向边也被算入其中。
即 G′=(V′,E′),其中 V′=V,E′={(u,v)∈E,p(u,v)>0}+{(v,u)∈E,p(u,v)>0}。通常我们认为反向边的容量 c(u,v)=0,反向边的流量 f(u,v)=−f(v,u),即正向边的相反数。
增广路是指一条在残留网络上从源点 s 到汇点 t 的路径。
EK 算法是一种找增广路算法,每次在残留网络中找一条增广路并构建新的残留网络,找不到增广路时,就找到了一个最大流。注意要反向建边,这样可以反悔流量。因为每次找的增广路不一定是最优的。
使用 EK 算法实现 P3376。
时间复杂度 O(nm2),比较适用于稀疏图。
2.2 Dinic 算法
Dinic 算法也是基于增广路的算法。与 EK 算法不同,Dinic 算法在每个残留网络上不止会找一次增广路,而会多次增广,直到找不到新的路径时再重构残留网络,接着继续增广。
然而这样做复杂度并不会更优多少,Dinic 在每次对一个残留网络增广前,会把图分层。设 di 表示点 i 的层数,那么 ds=0,di 为 i 到 s 的最短路径,注意这里和边权无关,即 BFS 第一次搜到的就是最短路径。那么每次增广时,对于当前点 u,为了避免环,每次我们只找 dv=du+1 的边增广。
Dinic 算法通常还会有当前弧优化,即对于每一个残留网络,多次增广时,如果一条边增广过,那么对于这次的多次增广,这条边永远都不会重新增广。
使用 Dinic 算法实现 P3376。明显比 EK 快不少,复杂度 O(n2m),适用于稠密图,稀疏图效率与 EK 差不多。比较推荐使用。
此外最大流还有基于增广路的 MPM,ISAP 和基于预留推进的 HLPP 等其他算法,但是 Dinic 通常不会被卡,其他算法暂时不介绍。
3、最小割
对于一个网络,定义一个割为一种点集划分方式。即将 V 划分成两个点集 S,T,使得 s∈S,t∈T。
定义一个割的容量 p(S,T) 为连接 S 集合的某个点和 T 集合的某个点的容量和。即 p(S,T)=u∈S,v∈T∑c(u,v)。通常 p(S,T) 可以表示为 p(s,t),即将 s 和 t 两个点分进两个集合,其他节点随意分配。
最小割即容量最小的割。
接着考虑如何求最小割。
结论:一个网络的最大流等于这个网络的最小割。
对于任意流 F 和任意割 S,T,都有该可行流的流量 v(F)≤c(S,T)。
证明:可行流的流量 v(F)=(s,v)∈E∑f(s,v)−(u,s)∈E∑f(u,s)=u∈S,v∈T∑f(u,v)−u∈T,v∈S∑f(u,v)≤u∈S,v∈T∑f(u,v)≤c(S,T)。
显然流量 ≤ 容量。取等时容量最小,即 S 不存在入边,也就是最大流时。
为什么流量 =S 出边权值和 −S 如边权值和?一开始我也不太理解。S 里,除了 s,其余每个点满足流量守恒,所以入边和等于出边和,这些出边和一直拓展到 t,但是注意到有些点尽管属于 S,但是有来自 T 的入边,那么这些流量就不是 s 流出的,删去即可。
代码和最大流完全一致,不给出。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具