网络流总结(一)

来源:互联网 发布:sandbox软件 编辑:程序博客网 时间:2024/05/13 19:01

一、个人心得:

今天对这些天网络流的学习做一个总结,最大流、二分图最大匹配、最小点覆盖、最小路径覆盖、最大独立集、最大点权独立集这样一路走来。其实对这些问题的熟悉仅仅只是一些皮毛而已,我比较不善于去论证和深究其中的联系,所以对这些个问题也只停留在理解的基础上,还不能很好地活学活用。建立流模型、二分图模型这点很重要,也是解题的关键,如果建立好了模型,那么问题就会迎刃而解了。


二、网络流学习中的基本定义和定理:

流网络:G = (V , E) 是一个有向图,其中每条边 (u, v) ∈ E 均有一非负容量 c (u , v) ≥ 0.s表示源点,t表示汇点。

残留网络:直观上讲,是由可以容纳更多网络流的边所组成。在不超过容量c ( u , v ) 的条件下,从u 到 v之间可以压入的额外网络流量就是(u , v) 的残余容量,可有公式定义:cf(u, v) = c(u, v) - f(u, v).

增广路经:为残留网络 Gf 中从 s 到 t 的一条简单路径。

流网络的割:流网络G = (V , E) 的割(S , T) 将V 划分为S 和 T = V - S两部分,使得s ∈ S,t ∈T。

最大流最小割定理:如果f 是具有源点 s 和 汇点 t 的流网络G = (V , E) 中的一个流,则下列条件是等价的:

1)f 是 G 的最大流

2)残留网络Gf 不含增广路经

3)对G 的某个割 (S, T) ,有 | f | = c ( S , T )

于是得出:最大流 = 最小割    //网络流的割或许是精髓,但是我好像没有理解

最小割的求解步骤:先求的最大流,再在得到最大流 f 的残余网络 Gf 中,从 s 开始深度优先遍历(DFS),所有遍历到的点,即构成点集S。

若果想要更深入了解最小割,参见:http://wenku.baidu.com/view/986baf00b52acfc789ebc9a9.html

最大流这个博客中讲的不错:http://www.cppblog.com/mythit/archive/2009/04/19/80470.html

二分图最大匹配:一个匹配是一个边的子集合 M ∈ E,且满足对所有顶点 v ∈ V,M中至多有一条边与v关联。最大匹配是最大势的匹配,在所有匹配中,边的权值和最大。

题型参考:http://blog.csdn.net/lhshaoren/article/details/7752944

最小点覆盖:用最少的点,让每条边都至少和其中一个点关联。

最小点覆盖数 = 最大匹配数

证明参见:http://www.cppblog.com/abilitytao/archive/2009/09/02/95147.html

最小点权覆盖:在所有覆盖集中,权值和最小的。

最小点权覆盖 = 最小割 = 最大流

最小路径覆盖:用最少的边,使之覆盖图中所有的顶点,且任何一个顶点有且只有一条路径与之关联。

最小路径覆盖数 = 顶点数 - 最大匹配数

证明参见:http://baike.baidu.com/view/2444809.htm

最大点独立集:用最多的边,组成一个点集,其中所有的点都不存在匹配关系。

最大点独立集 = 顶点数 - 最大匹配数。

最大点权独立集:在所有独立集中,权值和最大的独立集。

最大点权独立集 = 权值和 - 最小点权覆盖

三、涉及到的一些算法:

Ford_Fulkerson方法:用流网络的割来描述最大流的值,Ford_Fulkerson方法是一种迭代方法,开始时,对所有u , v ∈ V 有 f (u , v) = 0,然后在每次迭代中,通过寻找一条增广路经来增加流值,得到最大流。

伪代码:

Ford_Fulkerson(G, s, t)for each edge(u, v) ∈ E[G]do f[u, v] = 0f[v, u] = 0while there exists a path p from s to t in the residual network Gf//存在增广路经do cf(p) = min(cf(u, v) : (u, v) is in p)//找到增广路经中残余容量最小的边for each edge(u, v) in pdo f[u, v] -= cf(p)do f[v, u] += cf(p)


Edmonds_Karp算法:广度优先搜索寻找增广路经。算法复杂度:O(V*E*E)

具体代码参见:http://blog.csdn.net/lhshaoren/article/details/7748992

dinic算法:网络流最大流的优化算法之一,每一步对原图进行分层,然后用DFS求增广路径。算法复杂度:O(V*V*E),所以当边比较多时候比较适合使用

1、初始化流量,计算出残余网络2、根据残余网络计算层次图,如果汇点不在层次图中,则算法结束3、在层次图内用一次dfs过程增广4、转步骤2

具体代码参见:http://blog.csdn.net/lhshaoren/article/details/7765901


原创粉丝点击