众所周知,网络流是一类常用于求解最优化问题的算法,有着灵活的性质与较为优秀的复杂度
网络流学习的关键是对问题的抽象与建模,下面介绍一些常见的应用。
二分图上的应用
二分图最大独立集 \(=\) 二分图最小点覆盖 \(=n-\) 二分图最大独立集。
考虑最小点覆盖的构造:从左部点所有失配点开始,走“匹配边-非匹配边”交替的路径,标记所有经过的路径,最后取左部未被标记的点和右部被标记的点。
反应到网络流上就是从源点出发,沿所有有残流的边搜(所有边初始流量都为1),标记经过的点。
最大独立集就取最小点覆盖的补集。
下面给出大致证明:
首先证明构造与最大匹配一一对应。首先对应左部点一定匹配,否则会被当为出发点标记;然后对应右部点一定匹配,因为右部点一定由一条匹配边到达;最后一条匹配边不可能两端点都在点覆盖内,因为右部点可以通过此边标记左部点。
然后证明覆盖了所有边,即不存在左右点同时不在点覆盖内。分类讨论:若此边为匹配边,左部点只能从右部点搜到,那么右部点一定被标记;若为非匹配边,左部点就能从右部点转移。
二分图的构造在各类匹配问题十分常见,如网格图黑白染色,还有填充模板类的问题。
最小割
平面图最大流等于最小割,可以处理一些“选不选”的问题,下面是一些经典的构造。
P4313 文理分科
考虑如何表示选择文理,一个点分别向源汇,建权值为文科/理科贡献的边。
考虑对所有点再建两个个点表示周围相同能产生的贡献。将它四周的点与它向新点建边,流量inf,再将两点分别连接源汇点,建权值为周围全为文科/理科产生的贡献的边。
这样如果A点连源,B点连汇,并且A,B有连边,那么A,B必须割“相同选择”的边,或者两个都连源,那么要割掉另一条额外贡献。
答案就是所有贡献和减去最小割。
拓展:BZOJ3511 (权限)
对于选择相同产生贡献直接套用经典模型,考虑如何处理不同选择产生的代价 \(c\)。
考虑每次选择不同,会割去两条边,考虑给两条边分别加上 \(c\),再在总和中加入一个 \(c\),这样选择相同的时候,只割一个 \(c\) 刚好抵消。
P3227 [HNOI2013]切糕
考虑对立方体所有坐标建点,然后建 \((x,y,z-1) \to (x,y,z)\),源点连 \((x,y,0)\),\((x,y,R)\) 连汇点,容易知道所有 \((x,y)\) 只会割一条边。
考虑如何限制 \(D\),\(\forall k \ge D,(x,y,k) \to (x,y,k-D)\),流inf。
这样的话可以如果割了一对距离超过 \(D\) 的边,那么源汇依旧联通,不合法
这一类问题可以拓展成对于数列 \(\{A\}\),\(A_i \in [1,m]\),取 \(j\) 花费 \(a_{i,j}\),有若干约束 \(A_{u_i}-A_{v_i} \le w_i\),给变量赋值并最小化总代价。
更多应用可以参考 djq 在 WC2023 的课件。
[SHOI2010]最小生成树
首先其他边减 \(1\) 等价于此边加 \(1\)。
考虑Kruskal的过程,即对于所有小于等于当前边(权\(w\))的边加入时,保证不连通。
那么在原图保留权值小于当前边的边,边权改为 \(w-原边权\),跑个最小割。
上下界网络流
无源汇上下界可行流
将原图边权赋为 \(R-L\),跑最大流,但是可能有点不满足出流 \(=\) 入流。
考虑建立虚拟源点汇点,这样就可以补齐多余的流量。
给予点 \(i\) 点度 \(i\),那么对于边 \((u,v,l,r)\),将 \(d_u\) 减去 \(l\),\(d_v\) 加上 \(l\),最后 \(s \to u(d \ge 0)\),\(u(d \le 0) \to t\)。
若 \(s\) 的出边均满流,那么存在可行流。
有源汇上下界可行流
对源汇建 \(T \to S,val=\inf\),转换成无源汇。
有源汇上下界最大流
在可行流基础上再跑一边最大流。
有源汇上下界最小流
在可行流基础上再跑一边最大流,然后去 \(S \to T\) 的残流。
其他
给定 \([1,m]\) 中的 \(n\) 个区间 \([l_i,r_i]\),每个区间选择一次的代价为 \(w_i\),最多可以选 \(c_i\)次,要求使得任意点 \(j\) 被覆盖次数在 \([a_j,b_j]\)。
考虑 \(s \to 1\),\(i \to i+1\),\(m+1 \to t\),对于 \(l_i \to r_i+1,val=c_i\),流一次表示选择一次区间。给予源点出发极大流 \(\inf\),对 \(i \to i+1\) 权赋为 \([\inf-b_i,\inf-a_i]\),跑最小(大)费用上下界最大流。
P6967 [NEERC2016]Delight for a Cat
P3358 最长k可重区间集问题
CF818G Four Melodies
一个朴素的想法就是对所有符合条件的 \(i,j\) 建边,但是这是 \(n^2\) 级别的,过不了。
考虑对所有点拆出 \(id1,id2\) 表示 \(\bmod 7\) 同余和 差的绝对值为\(1\),以及入点 \(in\) 出点 \(out\)。
下面所有 \(j\) 都是 \(i\) 后第一个满足条件的点。
\(a_i \equiv a_j \pmod 7,out_i \to id1_j,id1_i \to id1_j\),表示 \(i\) 之后可以选 \(j\) 或者可以跳过 \(i\) 选 \(j\)。
\(a_i-a_j=-1,out_i \to id2_j (\inf,0)\),表示选 \(i\) 之后选 \(j\)。
\(a_i-a_j=1,out_i \to id2_j (\inf,0)\),表示选 \(i\) 之后选 \(j\)。
\(a_i=a_j,id2_i \to id2_j (\inf,0)\),表示跳过 \(i\) 选相同值的 \(j\)。
为限制每个点只选一次 \(in_i \to in_j (1,1)\)。
最后 \(s \to in_i (\inf,0)\),\(out_i \to t (\inf,0)\),\(id1_i \to in_i (\inf,0)\),\(id2_i \to in_i (\inf,0)\)。
最大费用最大流。