最小生成树

常用的有三种方法

相关代码,请参考《北大ACM2485 - Highways(最小生成树)


朴素Prim算法

Prim算法思路

从任意一个顶点(它就是最后生成树的根结点)开始,首先设置和它相邻顶点的权值(指该顶点和相邻顶点已知长度最小边的长度;初始值是无穷大),然后将所有未加入生成树顶点中权值最小的顶点加入到生成树中,然后更新新加入生成树顶点相邻顶点的权值;依次执行,直到所有顶点都加入到了生成树中。

算法的正确性,就不做详细说明了,这是一个贪心算法。


朴素Prim分析

每次从其中选择一个未处理过的权值最小的顶点,花销是O(n);然后更新和该顶点相连的顶点的权值,花销是o(n);共需要进行n次,花销是o(n),以上三个步骤是嵌套关系,所以花销是o(n3)。


Prim + heap算法

朴素Prim算法在寻找未处理过的权值最小的顶点时,由于没有将这些顶点的权值进行排序,所以每次寻找这个权值最小的顶点都需要O(n)的时间;在更新顶点的权值时,是有机会对顶点权值进行排序的。这些顶点的权值应用优先级队列管理,那么更新一个顶点的权值需要O(lgn),寻找并删除权值最小的顶点需要O(1)+O(lgn)。

所以通过优先级队列,所以效率得到了提高,该算法的时间复杂度是O(ElgV),所以,当边数比较少时,效率提高得会很明显。


Kruskal算法

思路

以边为考虑对象,每次选择最小的边,将该边和顶点加入到生成树中:

1. 刚开始时,是n个顶点组成的森林,生成树还为空;

2. 选择最小的边,判断这个边的两个顶点是否已经在一个树中了,如果已经在了,就丢弃这个边,因为加上这个边,这个树就会有回路;

3. 当所有的边,或者所有的顶点都处理后,就可以停止了,这个时候就组成了一个最小生成树;


分析

1. 这个过程是先有n个只有一个节点的树,慢慢变成了有多个节点的树,最后这些树组成了一个树;

2. 在这个过程中,用的最多的是集合的方法,有判断两个节点是否属于一个树(两个元素是否属于一个集合)、合并两棵树(合并两个集合),所以,很自然地想到使用《不相交集合》中的理论。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值