Prim算法
Posted mr94kevin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Prim算法相关的知识,希望对你有一定的参考价值。
多么痛的领悟!
不要认为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的初始化,还有一种写法。开始时并没有标记起点,而是将起点到Vnew中某个点的最小边权置为0,这样就需要循环n次(相当于需要将n个点放入Vnew中)。
另外,Prim还可以使用堆和邻接表进行优化。自己尝试写了一个,但效率还不如邻接矩阵的Prim,可能是自己写的不好,而且Kruskal+O(n^2)的Prim基本可以满足要求,这里就不再多说了。
以上是关于Prim算法的主要内容,如果未能解决你的问题,请参考以下文章