话说线上赛有啥游记好写的…但是作为惯例还是写一个
__builtin_popcount原理
小学期题用了这个函数
这个函数用来数二进制数中1的个数unsigned int
二进制表示下最右端是不是1
Dinic算法
本文讲解Dinic算法的思路
关于残余网络和增广路等概念的说明
问题
当$F$较大时
思路
Dinic算法的核心是每次寻找最短的增广路
证明
下面证明
此时有结论
下面使用数学归纳法
那么沿该路径中任何一条边编号增加不超过1
类似于上面
综上
优化
首先
算法描述
下面的算法只是大致的描述
Dinic算法 ( 输入 ) 网络$G(V,E)$ 输出 : 最大流$max\_flow$ : 步骤0. [准备]建立数组$iter[V]$
定义$max\_flow\gets0$ , 用邻接表$G[V]$存储网络 , ; 步骤1. [建立分层图]bfs(s,0)
当bfs(u,n)时 , 若$n_u$已定义 , 返回 , 否则记$n_u=n$ ; 并对$G[u]$中的所有元素$v$进行bfs(v, n+1) , 清零$iter[]$数组 。 。 步骤2. [有增广路吗
]若$n_t$未定义 ? 退出算法 , 返回$max\_flow$ , 。 步骤3. [寻找增广路]在$G$上DFS
寻找从$s$到$t$的简单路径 , 要求该路径上每条边$e\langle u,v\rangle$可用权值$(w_e-f_e)$大于0 , 并且$n_v>n_u$ , 若找到 。 记该路径上的权值最小的边权值为$f$ , 否则$f\gets0$ , DFS(u)时按顺序遍历$G[u]$ 。 若$G[u][i]$不可用 , $iter[u]\gets iter[u]+1$ , 。 步骤4. [找到了
更新残余网络]如果$f>0$ , 置$max\_flow\gets max\_flow+f$ , 对路径上的每条边$e$ 。 置$f_e\gets f_e+f$ , 记其反向边为$e'$ 。 置$w_{e'}\gets w_{e'}+f$ , 返回步骤3 。 。 步骤5. [没有找到]如果$f=0$
返回步骤1 , 。
复杂度
由于每次dfs都至少使一条边满流
模板
1 |
|
如有发现模板的错误请联系我指正
网络流
最大流问题
举个例子
有许多类似的问题
对无重边与自环的有向图$G(V,E)$
若每条边$e\in E$有一个权值$w_e$ , 称作该边的容量 ( ) 且$s\in V,t\in V$ , 称该图为一个网络 , 若一个有向图$G'(V,E)$满足 。 $G'$与$G$完全相同 : 除去每条边$e\in E$有另一个权值$f_e$ , 称作该边的流量 ( 以外 ) 并且对$\forall u\in V,u\ne s,u\ne t$满足$\sum\limits_{e=\langle u,v\rangle}{f_e}=\sum\limits_{e=\langle v,u\rangle}{f_e}$ ; 即流入每个顶点的流量等于流出的流量 ( ) 那么称该有向图$G'$为网络$G$上的一个流 , 该流的流量$f$定义为$\sum\limits_{e=\langle s,u\rangle}{f_e}$ , 一个网络的最大流是指该网络的所有流中流量最大的那个 。 。
通常在不引起歧义的情况下
对上面的抽象模型
算法名 | 算法分类 | 复杂度 |
---|---|---|
Ford-Fulkerson算法 | 增广路 | $O(FE)$ |
Dinic算法 | 增广路 | $O(n^2m)$ |
HLPP | 预流推进 | $O(n^2\sqrt{m})$ |
Ford-Fulkerson算法
本文讲解Ford-Fulkerson算法的思路
分析
朴素算法
朴素的想法
上面的图中
所以上述的算法是错误的
改进
观察图3
从图4看
解释
仔细观察图2和图3
所以
上面的做法
于是对一个流
算法描述
对网络上的每个流$G(V,E)$
Ford-Fulkerson算法
输入
网络$G$ : 一个图$G(V,E)$ ( $E$中的边$e$有权重$w_e\in\mathbb{N_+}$ , ) $max\_flow=0$ , 输出
该网络上的最大流的流量$f$ : 步骤0. [建立反向边]定义$max\_flow\gets0$
用邻接表G[V]存储网络 , 对$E$中的每条边$e=\langle u,v\rangle$ ; 作其反向边$e'=\langle v,u\rangle$ , 并置$w_{e'}\gets0$ , 。 步骤1. [寻找增广路]在$G$上DFS
寻找从$s$到$t$的简单路径 , 要求该路径上每条边可用权值$(w_e-f_e)$大于0 , 若找到 。 记该路径上的权值最小的边权值为$f$ , 否则$f\gets0$ , 。 步骤2. [找到了
更新残余网络]如果$f>0$ , 置$max\_flow\gets max\_flow+f$ , 对路径上的每条边$e$ 。 置$f_e\gets f_e+f$ , 记其反向边为$e'$ 。 置$w_{e'}\gets w_{e'}+f$ , 返回1 。 。 步骤3. [没有找到]如果$f=0$
输出$max\_flow$ , 算法结束 , 。
最大流不会超过从$s$出发的所有边的边权和
证明
在Ford-Fulkerson算法结束后的残余网络上没有$s\rightarrow t$路径
结论1
结论2
对于任意一个流
而对于残余网络
也可以用反证法
至此
模板
1 |
|
如有发现模板的错误请联系我指正
POJ2987-Firing
这是一道最大点权闭合图的问题