网络流简陋入门
网络流复杂度
感觉这个证明写的人好少啊......
最大流
FF
这个没有什么好说的,每次暴力找增广路答案是单增的,每次增广的复杂度是 \(O(|E|)\) 的,所以总复杂度是 \(O(|E||F|)\),其中 \(|F|\) 表示最大流的大小,边权相同的完全图就可以卡到这个级别,但是我不知道有没有更满的
EK
首先,每次 \(bfs\) 找增广路是 \(O(|E|)\) 的,这很显然,每条边只会被扫到 \(O(1)\) 次
用 \(d(a,b)\) 表示 \(a,b\) 在残量网络上的最短路(边权为 \(1\),有流量就连边),\(G\) 表示残量网络
引理
引理 \(\mathrm{A}\):每次增广后,\(\forall u\in G,d^\prime(s,u)\ge d(s,u)\)
用自然语言说就是每次增广之后点到源点的距离单调不减(这里和汇点是对称的,用哪个都可以)
假设一次增广之后,残量网络从 \(G\) 变成了 \(G^\prime\)
考虑反证,假设 \(U=\{u|d^\prime(s,u)<d(s,u)\}\),也就是所有到源点距离变小的点的集合
设 \(u\) 为 \(\forall x\in U\) 中 \(d^\prime(s,x)\) 最小的 \(x\)
设 \(G^\prime\) 从 \(s\) 到 \(u\) 的最短路上 \(u\) 前面的一个点为 \(v\)
由定义有 \(d^\prime(s,u)=d^\prime(s,v)+1\) 和 \(d^\prime(s,u)<d(s,u),d^\prime(s,v)\ge d(s,v)\)
代入就可以知道 \(d^\prime(s,u)=d^\prime(s,v)+1<d(s,u)\)
如果 \(v\rightarrow u\) 是一条新加的反边,那么 \(G\) 存在边 \(u\rightarrow v\),可知 \(d(s,u)<d(s,u)+1=d(s,v)\)
代回上式,有 \(d^\prime(s,u)=d^\prime(s,v)+1<d(s,u)<d(s,v)\)
与 \(d^\prime(s,v)\ge d(s,v)\) 矛盾
否则 \(v\rightarrow u\) 是 \(G\) 和 \(G^\prime\) 共有的边,可知 \(d(s,u)=d(s,v)+1\)
与假设中 \(d^\prime(s,u)<d(s,u)\) 矛盾
至此引理 \(\mathrm{A}\) 得证
证明
每次增广都有一条关键边,这条边的剩余容量是增广路上最小的
考虑 \(u\rightarrow v\) 成为关键边的次数,\(G\) 上的边都可能成为关键边 \(1\) 次,之后 \(u\rightarrow v\) 想再成为关键边,需要 \(v\rightarrow u\) 成为关键边
设两次转化时,残量网络分别为 \(G\) 和 \(G^\prime\)
不难得出 \(d(s,v)=d(s,u)+1\) 和 \(d^\prime(s,v)+1=d^\prime(s,u)\)
由引理 \(\mathrm{A}\),\(d(s,v)\le d^\prime(s,v)\),故 \(d^\prime(s,u)=d^\prime(s,v)+1\ge d(s,v)+1=d(s,u)+2\)
故每次成为关键边后,想再成为关键边需要 \(d(s,u)\) 增加 \(O(1)\),这个过程至多重复 \(O(|V|)\) 次
又因为一共有 \(|E|\) 条边,所以增广至多重复 \(O(|V||E|)\) 次
每次增广是 \(O(|E|)\) 的,于是 EK 的复杂度就是 \(O(|V||E|^2)\) 的(不会卡)
dinic
证明
首先,建出分层图是 \(O(|E|)\) 的,之后每次 dfs 都会至少减少一条边,于是 dfs 次数限制是 \(O(|E|)\),每次分层图上 dfs 是 \(O(|V|)\) 的,所以每次建出分层图之后所有操作一共是 \(O(|V||E|)\) 的
在证明 EK 的引理 \(\mathrm{A}\) 时,我们提到 \(d(s,u)\le d^\prime(s,u)\),对称的,还有 \(d(u,t)\le d^\prime(u,t)\)
于是容易得到 \(d(s,t)\le d^\prime(s,t)\)
设 \(d(s,t)=d^\prime(s,t)\)
这样一定是存在一条边 \(v\rightarrow u\) 作为反向边出现,使得一条新的路径出现
不妨设 \(d(s,t)=d(s,u)+1+d(v,t)=d^\prime(s,v)+1+d^\prime(u,t)=d^\prime(s,t)\)
更为细致的约束条件还有
由引理 \(\mathrm{A}\),\(d(s,u)\le d^\prime(s,u),d(v,t)\le d^\prime(v,t)\)
可得
显然与 \(d(s,t)=d^\prime(s,t)\) 的假设矛盾
故 \(d^\prime(s,t)>d(s,t)\)
所以建立分层图至多 \(|V|-1\) 次,dinic 的复杂度就是 \(O(|V|^2|E|)\)
ISAP 大概只能算是 dinic 的优化,渐进复杂度并没有更优,就不写了(据说可以做到 \(O(|V|^3)\),那不是和 HLPP 一个复杂度了)
值得注意的是,如果不加当前弧优化的话,在分层图上 dfs 就是 \(O(|E|)\) 而不是 \(O(|V|)\) 的
伸缩优化
把边按流量的 \(\operatorname{highbit}\) 分段,从大到小,把所有 \(\operatorname{highbit}\) 相同的边加入残量网络,每次新加入的边只会使得低位产生变化,所以建立分层图的次数就是 \(O(|V||E|\log |F|)\)(一定没有讲清楚,因为我自己口胡的)
HLPP
竟然写之前我不会那就记一下吧
算法
用 \(c(u,v)\) 表示 \(u\rightarrow v\) 这条边的容量
每个点 \(i\) 有超额流量 \(e_i\),高度 \(h_i\)
初始时,设 \(h_i=d(i,t),e_i=0\),特殊的 \(h_s=n\)
考虑维护一个以 \(h\) 为键值的优先队列
对于所有 \(s\) 的出边 \(s\rightarrow v\),置 \(e_v\leftarrow e_v+c(s,v)\),并将 \(v\) 置入队列中
每次取出队首 \(u\),枚举其出边 \(u\rightarrow v\),如果 \(h_u=h_v+1\),那么就将 \(min(e_u,c(u,v))\) 的流量推送给 \(e_v\),同时在 \(e_u\) 中减少等量的流量。枚举所有出边后,如果 \(e_u>0\),置 \(h_u\leftarrow h_v+1\),其中 \(v\) 是 \(u\) 所有出边中还有容量并且 \(h_v\) 最小的点,将 \(u\) 重新入队,这一过程称为 \(\text{relabel}\)
重复上述过程直到队列为空,此时 \(e_t\) 就是答案
证明
咕咕咕咕咕咕
最小费用最大流
EK
网上大多数做法(包括我之前写的),都是直接把 EK 的 bfs 换成 spfa,以费用作为边权跑最短路,然后可以被卡成指数级(不过需要指数级的边权,所以一般还是安全的)
如果是先分层再 spfa,好像可以做到 \(O(|V|^2|E|^2)\),不过没有写过,也不知道对不对
原始对偶
这个才是正确的做法,咕咕咕
单纯形
我只会用这个做最大流,最小费用如果给流量乘上巨大的权值不知道会不会卡成指数级,不过应该可以过