网络流简陋入门

网络流复杂度

感觉这个证明写的人好少啊......

最大流

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\)

\[\begin{align*} d(s,v)\le d^\prime(s,v)&\Rightarrow d(s,v)+1\le d^\prime(s,v)+1\\ &\Rightarrow d(s,u)\le d^\prime(s,u) \end{align*} \]

与假设中 \(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)\)

更为细致的约束条件还有

\[\begin{align*} d(s,u)+1&=d(s,v)\\ d^\prime(s,v)+1&=d^\prime(s,u) \end{align*} \]

由引理 \(\mathrm{A}\)\(d(s,u)\le d^\prime(s,u),d(v,t)\le d^\prime(v,t)\)

可得

\[\begin{align*} d^\prime(s,t)&=d^\prime(s,v)+1+d^\prime(u,t)\\ &\ge d(s,v)+1+d(u,t)\\ &=d(s,u)+2+d(u,t)\\ &=d(s,t)+2 \end{align*} \]

显然与 \(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)\),不过没有写过,也不知道对不对

原始对偶

这个才是正确的做法,咕咕咕

单纯形

我只会用这个做最大流,最小费用如果给流量乘上巨大的权值不知道会不会卡成指数级,不过应该可以过

posted @ 2022-10-10 14:11  嘉年华_efX  阅读(24)  评论(0编辑  收藏  举报