博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
最小生成树 普莱姆(prim)算法
阅读量:6094 次
发布时间:2019-06-20

本文共 1773 字,大约阅读时间需要 5 分钟。

  文章作者:ktyanny 文章来源: 转载请注明,谢谢合作。  

   

  ktyanny最近很心烦,因为前天兴致勃勃想写个prim算法,结果很郁闷,看了两下也没想到怎么实现,囧了半天放弃了…… 但是还是不死心呐,一大早起来,不对劲,怎么舍友全走了,原来我已经睡过了两节课了,要不是肚子饿了的话我可能还会继续睡下去的。那就待会去上三四节的os课吧,先打开电脑去农场看菜回来,哇咔咔,好多菜可以摘啊,看来起床时是摘菜的最佳时间呐。

  从农场拿了个大丰收回来,又想起心里那个结还没了断,又拿起算法导论左看右看的,还是没感觉,汗……突然想起严蔚敏阿姨那本数据结构,诶,写得倒是蛮详细的,仔细数了一下,嘿嘿,13行代码,小case,嘎嘎……二话不说看完,恍然大悟中,上os课的时候,就拿起算法导论的那个图左画右画的,就是下面这个图:(在这里强调一下,如果你不知道最小生成树的概念,可以点击查看最小生成树得到概念和性质)

 

 

   上面的这个图是个很好的例子,其实不用不明白,这个图的最小生成树是不唯一的,认真思考就知道为什么了。

  留念一下os课上的我的鬼画虎的作品哈哈……(没带相机,吃完饭回到宿舍拍的)

 

   好了,流水账就记录那么多了。

   普里姆算法的基本思想:

  从连通网络 N = { V, E }中的某一顶点 u0 出发,选择与它关联的具有最小权值的边(u0, v),将其顶点加入到生成树的顶点集合U中。以后每一步从一个顶点在U中,而另一个顶点不在U中的各条边中选择权值最小的边(u, v),把它的顶点加入到集合U中。如此继续下去,直到网络中的所有顶点都加入到生成树顶点集合U中为止。

 

  Prim算法的形式描述如下:

    置T为任意一个顶点;
    求初始候选边集;
    
while
(T中结点数<n)
     {
    从候选边集中选取最短边(u,v);
     将(u,v)及顶点v,扩充到T中;
    调整候选边集;
      }

 

   

  为了更方便了解,贴上几个刚刚拍下来的prim算法过程的图片吧

 

   好吧,就这样吧。

  下面是写得很辛苦的代码:

/*
by ktyanny
2009.12.15
*/
#include 
<
stdio.h
>
#include 
<
stdlib.h
>
#include 
<
iostream
>
using
 
namespace
 std;
const
 
int
 MAXN 
=
 
0x7fffffff
;
const
 
int
 MAX 
=
 
105
;    
/*
顶点上限
*/
typedef 
int
 vrtype;
vrtype g[MAX][MAX];    
/*
图的带权邻接矩阵
*/
vrtype prim(vrtype g[][MAX], 
int
 n)
{
    
int
 i, j, k, minn, closest[MAX], ans 
=
 
0
;
    vrtype lowcost[MAX];
    
for
(i 
=
 
2
; i 
<=
 n; i
++
)
    {
        lowcost[i] 
=
 g[
1
][i];
        closest[i] 
=
 
1
;
    }
    closest[
1
=
 
0
;    
/*
第一个节点是在U集合里的
*/
    
for
(i 
=
 
2
; i 
<=
 n; i
++
)
    {
        minn 
=
 MAXN;
        k 
=
 i;
        
for
(j 
=
 
1
; j 
<=
 n; j
++
)
        {
            
if
(lowcost[j] 
<
 minn 
&&
 closest[j] 
!=
 
0
)
            {
                minn 
=
 lowcost[j];
                k 
=
 j;
            }
        }
        
/*
        打印边        
        printf("(%c, %c)", closest[k], k);    
        
*/
        ans 
+=
 minn;
        closest[k] 
=
 
0
;
/*
k并入U集合
*/
        
for
(j 
=
 
2
; j 
<=
 n; j
++
)
        {
            
if
(closest[j] 
&&
 g[k][j] 
<
 lowcost[j])
            {
                lowcost[j] 
=
 g[k][j];
/*
更新最小权值
*/
                closest[j] 
=
 k; 
/*
记录新的起点
*/
            }
        }
    }
    
return
 ans;
}

 

 

   

转载于:https://www.cnblogs.com/ktyanny/archive/2009/12/15/1625020.html

你可能感兴趣的文章
SqlServer表名称定义
查看>>
jquery操作select(取值,设置选中)
查看>>
浅谈无线h5开发
查看>>
关于裸婚,没事F5刷豆瓣是不够的!
查看>>
【FJOI2015】金币换位问题
查看>>
HighChar
查看>>
window上安装pymysql
查看>>
控件调用函数
查看>>
activity的启动模式
查看>>
Android主线程、子线程通信(Thread+handler)
查看>>
gitlab配置邮箱
查看>>
Win10桌面奔溃怎么办?雨林木风Win10奔溃解决方法教程
查看>>
mysql Inoodb 内核
查看>>
Redis 基础
查看>>
UITextField的returnkey点击事件
查看>>
特殊字体引用
查看>>
owlcar 用法心得 自定义导航
查看>>
数据结构 学习笔记03——栈与队列
查看>>
DB2 OLAP函数的使用(转)
查看>>
数学之美系列二十 -- 自然语言处理的教父 马库斯
查看>>