•参考资料
[1]: 最大流入门
[2]: 算法讲堂
[3]: Dinic优化
•理解
通俗理解最大流就是在某个时间点从源点S到终点T流过的水的最大值
如图,最大流为9
①线路 S->3->T:可以流过$min(5,3)=3$,然后$S->3$还有$5-3=2$的剩余
②线路 S->1->2->T:可以流过$min(5,6,10)=5$,然后$1->2$还有$6-5=1$的剩余,$2->T$还有$10-5=5$的剩余
③线路S->3->1->2->T: 可以流过$min(2,3,1,5)=1$
最大流$=①+②+③=9$
•算法
将图分层,每一层都是按照不同方式的几条从原点到汇点的路径
利用bfs寻找所有的分层方法,分完层利用dfs去试探,找到所有分层方式中水流最大的一种
•优化
- 当前弧优化
对于一次 bfs() 后寻找增广路来说,如果询问了一条路的编号为 a 时,那么不再会通过这条路增广。
比如已经对$1->2->3$进行了增广,那在到$2$时,$2->3$已经不会增加流量了,所有可以直接略过 (一般用处不大...)
- 多路增广
dfs时一次找到该点u所有的增广路,用一个$flow$记录流向u的流量,用$nowflow$记录流出u的流量
$nowflow$的计算就需要通过u流向的点来计算。$nowflow$肯定是下于等于$flow$的,当$nowflow==flow$时可以直接$break$
在增广时对正向边和反向边操作有个小技巧,因为在加边时正向边和反向边是一起加入的一前一后,所以两条边是相邻的
正向边序号^1=反向边序号,反向边序号^1=正向边序号。前提是第一条边序号是偶数,所以向前星的下标从0开始的
- 炸点优化
如果当前 u 点伸展完后发现过这个点没有任何增广路被发现,即当前点$nowflow==0$ ,
则说明增广路不可能通过该点伸展,使得d[u] = -2,不再伸展这个点
•模板
•习题