贪心-最小生成树

来源:互联网 发布:淘宝外围商品销量要求 编辑:程序博客网 时间:2024/06/06 08:43

1.用贪心算法设计策略可以设计出构造最小生成树的有效算法。这里介绍的构造最小生成树的Prim算法Kruskal算法都可以看作是应用贪心算法设计策略的例子。尽管这2个算法做贪心选择的方式不同,它们都利用了下面的最小生成树性质

  设G=(V,E)是连通带权图,U是V的真子集。如果(u,v)ÎE,且uÎU,vÎV-U,且在所有这样的边中,(u,v)的权c[u][v]最小,那么一定存在G的一棵最小生成树,它以(u,v)为其中一条边。这个性质有时也称为MST性质

2Prim算法

  设G=(V,E)是连通带权图,V={1,2,…,n}。

  构造G的最小生成树的Prim算法的基本思想是:首先置S={1},然后,只要S是V的真子集,就作如下的贪心选择选取满足条件iÎS,jÎV-S,且c[i][j]最小的边,将顶点j添加到S中。这个过程一直进行到S=V时为止。

  在这个过程中选取到的所有边恰好构成G的一棵最小生成树

利用最小生成树性质和数学归纳法容易证明,上述算法中的边集合T始终包含G的某棵最小生成树中的边。因此,在算法结束时,T中的所有边构成G的一棵最小生成树。

  例如,对于右图中的带权图,按Prim算法选取边的过程如下页图所示。



在上述Prim算法中,还应当考虑如何有效地找出满足条件iÎS,jÎV-S,且权c[i][j]最小的边(i,j)。实现这个目的的较简单的办法是设置2个数组closest和lowcost。

  在Prim算法执行过程中,先找出V-S中使lowcost值最小的顶点j,然后根据数组closest选取边(j,closest[j]),最后将j添加到S中,并对closest和lowcost作必要的修改。

  用这个办法实现的Prim算法所需的计算时间

3Kruskal算法

  Kruskal算法构造G的最小生成树的基本思想是,首先将G的n个顶点看成n个孤立的连通分支。将所有的边按权从小到大排序。然后从第一条边开始,依边权递增的顺序查看每一条边,并按下述方法连接2个不同的连通分支:当查看到第k条边(v,w)时,如果端点v和w分别是当前2个不同的连通分支T1和T2中的顶点时,就用边(v,w)将T1和T2连接成一个连通分支,然后继续查看第k+1条边;如果端点v和w在当前的同一个连通分支中,就直接再查看第k+1条边。这个过程一直进行到只剩下一个连通分支时为止。

例如,对前面的连通带权图,按Kruskal算法顺序得到的最小生成树上的边如下图所示。



关于集合的一些基本运算可用于实现Kruskal算法。

  按权的递增顺序查看等价于对优先队列执行removeMin运算。可以用实现这个优先队列。

  对一个由连通分支组成的集合不断进行修改,需要用到抽象数据类型并查集UnionFind所支持的基本运算。

  当图的边数为e时,Kruskal算法所需的计算时间是      。当        时,Kruskal算法比Prim算法差,但当       时,Kruskal算法却比Prim算法好得多。


0 0
原创粉丝点击