码迷,mamicode.com
首页 > 编程语言 > 详细

Prim算法

时间:2018-09-02 23:53:01      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:one   sub   color   技术   集合   写的不好   for   通过   hide   

多么痛的领悟!

不要认为Prim不常见就用不到!

和Kruskal一样,Prim算法也是用来求MST的,也是体现了贪心的思想。

不同的是,Kruskal是针对边而言的,Prim是针对点而言的。Kruskal适用于稀疏图,Prim适用于稠密图,更值得一提的是,Prim可以不必保存每条边。

算法思想是,设定两个集合Vnew和Enew,先选中一个起点加入到Vnew中,再从V-Vnew(在V中且不在Vnew中)中选择一个点,使得该点到Vnew中某个点的边权最小,将这条边加入Enew中,将这个点加入Vnew中,不断重复该过程,直到Vnew=V。

因为每次是通过某个点到已建好的树的最小边权将该点加入到生成树中的,所以最终构造出来的一定是最小生成树。

技术分享图片
 1     vis[1]=1; //开始先将起点加入到Vnew
 2     for(int i=2;i<=n;++i) minw[i]=G[i][1];
 3     int index,mmin;
 4     for(int i=1;i<n;++i) {
 5         mmin=1e5+5;
 6         for(int j=1;j<=n;++j) //取出到Vnew中某个点边权最小的点
 7             if(!vis[j]&&minw[j]<mmin) index=j,mmin=minw[j];
 8         vis[index]=1;
 9         ans+=mmin;
10         for(int j=1;j<=n;++j) //用每次新加入的点更新其他点到Vnew中点的最小边权
11             if(!vis[j]&&G[j][index]<minw[j]) minw[j]=G[j][index];
12     }
Prim模板(邻接矩阵)

对于Prim的初始化,还有一种写法。开始时并没有标记起点,而是将起点到Vnew中某个点的最小边权置为0,这样就需要循环n次(相当于需要将n个点放入Vnew中)。

另外,Prim还可以使用堆和邻接表进行优化。自己尝试写了一个,但效率还不如邻接矩阵的Prim,可能是自己写的不好,而且Kruskal+O(n^2)的Prim基本可以满足要求,这里就不再多说了。

Prim算法

标签:one   sub   color   技术   集合   写的不好   for   通过   hide   

原文地址:https://www.cnblogs.com/Mr94Kevin/p/9575611.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!