普里姆(Prim)算法
- 普里姆算法的基本思想是:假设连通网络为 N=(V,E);
TE为N的最小生成树上边的集合,开始时TE为空集;
U为算法在构造最小生成树过程中已得到的顶点集,开始时U={ u0 }(u0属于V)。
(1) 算法从N中的某一顶点u0出发,选择与u0关联的具有最小权值的边(u0,vi),将顶点vi加入到生成树的顶点集合U中,(u0,vi)加入到集合TE中;
(2) 以后每一步从一个顶点在U中,而另一个顶点在(V-U)中的各条边当中选择权值最小的边(u,v)(u属于U,v属于V-U),把顶点v加入到集合U中,边(v,u)加入到集合TE中。
(3) 如此重复,直到网络中的所有顶点都加入到生成树顶点集合U(U=V)中为止。此时,TE中刚好有n-1条边,则T=(V,TE)为N的最小生成树。
- 例如,对于图7-18(a)所示的连通网络,图7-2l(a)~(f)给出了按普里姆算法构造最小生成树的过程。

- 在利用普里姆算法构造最小生成树过程中,需要设置一个辅助数组closearc[ ],以记录从V-U中顶点到U中顶点具有最小权值的边。对每一个顶点v属于V-U,在辅助数组中有一个分量closearc[v],它包括两个域:lowweight 和nearvertex。其中,lowweight中存放顶点v到U中的各顶点的边上的当前最小权值(lowweight=0表示v属于U);nearvertex记录顶点v到U中具有最小权值的那条边的另一个邻接顶点u(nearvertex=-1表示该顶点v为开始顶点)。
也就是说,通过 lowweight=0和 lowweight != 0将顶点分为已经在生成树中和还未包含入生成树中;用nearvertex记录到达当前节点的前一个结点,而因 为每次取权值最小,从nearvertex = -1到当前结点的nearvertex可以得到从第一个结点到当前结点的最短路径。
- 在下面的普里姆算法描述中,连通网络采用邻接矩阵作为存储结构,并假设普里姆算法从顶点A(设顶点A的序号为0)出发(即u0=0)。普里姆算法步骤如下:
1)初始化辅助数组closearc[]。
2)重复下列步骤3)和4)n-1次。
3)在closearc[]中选择lowweight≠0&&lowweight最小的顶点v,即选中的权值最小的边为(closearc[v].nearvertex,i)。将closearc[v].lowweight改为0,表示顶点i已加入顶点集U中,并将边(closearc[v].nearvertex,v)加入生成树T的边集合。
4)对V-U中的每一个顶点 j,如果依附于顶点 j 和刚加入U集合的新顶点 v 的边的权值Arcs[ v ][ j ]小于原来依附于 j 和生成树顶点集合中顶点的边的最短距离
closearc[ j ].lowweight,则修改 closcarc[ j ],使其lowweight=arcs[ v ][ j ],nearvertex=v。

代码实现
#include "AdjMatrixUndirGraph.h"
template<class ElemType,class WeightType> struct CloseArcType
{
WeightType lowweight;
int