最小生成树之Prim算法 优先队列版本

博客介绍了如何利用优先队列优化Prim算法,避免重复遍历已标记顶点,提高效率。通过建立link数组记录边的终点,简化查找与新顶点相连的边的过程。在代码实现中,遇到的问题及解决方案被详细阐述。
摘要由CSDN通过智能技术生成

http://www.cppblog.com/tanky-woo/archive/2013/02/18/126940.html

这个博客对prim讲解的很好

 

如果用传统的做法每次都要将集合内的元素遍历一遍,再与集合外的元素判断是否相连,再找出最小权值,然后把带有最小权值的那个终点记录下来,插入到集合内。

下次循环再从集合的第一个元素开始遍历,这样会浪费很多时间,于是乎,我想能不能把之前已经遍历过的顶点而且不是最小权的那些顶点存入列表中,下次再遍历的时候可以接着用,只需要把新的顶点插入进去就行了,那么怎么输出最小的权呢,大家都知道有个优先队列,就是把队列中的权值按由小到大排列,每次只需要把top()的权值pop掉就行了。

 

 

说了这么多,我们举个栗子(图就用上面那个博客的prim图)

假如从顶点1开始,与1相连的有1-2  1-3  1-4   找到1-3的权值为1 最小,于是把3这个终点的所有的相连的边插入到队列中,即3-5 3-6 3-2 3-4 因为1这个顶点已经被标记过所以,

3-1就不插入了,所以现在的队列中有 1-2 1-4 3-2 3-4 3-5 3-6 再找到top的最小的权值为3-6这个边的权4,所以把6记录下来,把3-6这个边pop掉,再重复之前的找和6相连的边。。。。。

 

我在写代码的时候遇到好几个问题。

 

   比如我在把3插入队列之后,怎么不用遍历找出和3相连的边,解决办法就是用代码中的link数组来保存与3对应的边的终点,

    那么和以3为起点的边有很多,那有几个呢,link[p][link[p][0]++] &

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值