首页 > 代码库 > 最大流-最小割 MAXFLOW-MINCUT ISAP

最大流-最小割 MAXFLOW-MINCUT ISAP

  简单的叙述就不必了。

  对于一个图,我们要找最大流,对于基于增广路径的算法,首先必须要建立反向边。

 

  反向边的正确性:

    我努力查找了许多资料,都没有找到理论上关于反向边正确性的证明。

    但事实上,我们不难理解,对于每条反向边,我们流过它相当于撤销了一条正向边的流量。

    并且它是必须的:

    技术分享

    而且从理论上,我们在加入反向边之后得到的最大流,我们从残余网络考虑。

    我们要认识到,反向边不会使最大流流量减少,这是很显然的。有flow<=flow‘。

    接下来我们考虑所有点的流量是否可以只用正向边得到。

    并且我们考察汇点,由于汇点没有出边,所有的反向边都是从它离开的,那么显然不会对汇点造成影响。

    对于其他点,我们考虑一条反向边的容量取决于正向边的流量,及总有flow_positive=capacity_negative,

    或者换一个说法,flow_positive=-flow_negative。

    也就是说,如果从这个点出去的流是通过u->v这条反向边出去的,这个流流向k,那么必然有相同流量的流从v->u,

    那么不如直接从v->k好了。(如果这个u->v->k包含其他反向边,那么就递归下去讨论,但问题规模减少。)

    这样就意识流的证明完了。

 

  最大流最小割定理:

    有一种普遍的证法,首先任意可行流的流量不可能大于任意一种割。即有最小割>=任意可行流。

    并且由于最大流算法,最大流的得出来的残余网络源点、汇点必然不连通,否则最大流可以更大(沿着联通的路径流过去可以更大)。

    这个时候最大流算法得到了其中一个割。

    即有最大流>=最小割。

    所以有最大流=最小割。

 

  要找到最大流,我们有一个非常直观的想法,不断的在残余网络中找S-T的路径,如果找到就流过去,流量自然而然的+1,这些便流量减少。

  这就是简易的Fold-Fulkerson算法,它是正确的。

 

 

  Fold-Fulkerson FF算法正确性证明:

    首先FF算法能够得到一个割,上面我们证明了割的容量总大于任意的流量,那么FF得到的流显然就是最大流了。

 

  在FF算法上,根据最短路的性质,可以证明每次根据残余网络的最短路径的可行路径流过去可以达到O(V^2E)的算法复杂度

——EK算法

  EK算法可以说是第一个SAP(Shortest Augment Path 最短增广路径)算法,在这之后的dinic只是一种扩展。

  事实上,在学习了之后,可以发现dinic和ISAP实际上十分相似。

  理论上ISAP是加了更多优化的。

  在利用预标号的技术后,ISAP应该是不会劣于Dinic的。但事实上poi的kos和NOI的海拔都使ISAP跪掉了(听说?)

  不过我觉得很有可能是写搓了。

 

  特别要注意,在分层图上,预标号是必需的。

  比如bzoj1001的狼抓兔子(本人ISAP跑了1200ms)中,如果不加预标号,一定是跑不过的。

  但加了之后,比dinic快2/3,并且比一些转了最短路的算法都要快一点。

 

 

Reference:

  1. https://tadvent.wordpress.com/2009/04/07/usaco-4-2-1-ditch-%E7%BD%91%E7%BB%9C%E6%9C%80%E5%A4%A7%E6%B5%81%E9%97%AE%E9%A2%98%E7%AE%97%E6%B3%95%E5%B0%8F%E7%BB%93/
  2. http://www.cs.yale.edu/homes/aspnes/pinewiki/MaxFlow.html
  3. https://en.wikipedia.org/wiki/Maximum_flow_problem
  4. http://blog.csdn.net/qq_21110267/article/details/43540483

最大流-最小割 MAXFLOW-MINCUT ISAP