网络流这种东西优化有很多种,比如sap,预流推进(其实那是另一种网络流,不算增广路了),单个人觉得最好写,同时效率不低的还是dinic(简易缩水版)。
要谈网络流首先你得知道EK算法吧,就是最简单的最大流。传统的最大流复杂度上限应该是n*m*m。
而dinic算法其实说难也不难,它好就好在非常好写。首先,我们有一个概念叫做“层次网络”。它是什么东西?简单来说,就是在最大流上从源点做一次bfs,我们新建一张图,每次碰到一个新的节点,我们就把它的深度定为找到它的点+1(源点深度为0),在新的图中保留该边。如果找到已经查过的节点,那么除非查过的节点的深度是当前正在bfs的节点的深度+1,那么我们在新图中保留这条边,否则不理它=w=。没错,这东西就是层次网络了。
而对于这样一张图,我们每次只要每次找到一条路能够到汇点就万事OK了,因为这就是一条增广路。我们通过dfs的方法去找增广路。而对于每一个层次网络,我们最多能够增广m次,因为每增广一次,就必然减少一条边(这个去看EK网络流吧,有证明)。
总结:我们最多构造n个层次网络(这个我也不会证=w=,但好像很有可信度),每个层次网络花费m的代价去bfs才能建好,而每建好一个网络,我们最多花费m次代价为n的dfs去增广,这样复杂度就是n*(m+n*m),差不多就是n*n*m,复杂度就低了。