这里最小生成树的定义不再赘述,直接给出Prim算法的思路与代码。
Prim算法的思路
首先对于一幅图,设G=(V,GE)为具有n个顶点的带权连通图。T=(U,TE)为生成的最小生成树,初始时,T中为空。
首先,在图中选择一个顶点进入T中。接着再从G中选择一条一个顶点仅在V中,另一个顶点在U中,并且权值最小的边加入集合TE,同时将该边仅在V中的那个顶点加入集合U。通俗来讲,就是在不在生成树中的顶点中选择一个顶点,使其到生成树中某个顶点的权值为最小。然后重复经历此过程直到所有顶点都被选取完,此时的T即为G的最小生成树。(可以自己举例推演)
代码实现过程
Prim算法的实现的核心是利用三个数组
int weights[maxn][maxn];//存权值
int dots[maxn];//存生成的最小生成树的顶点
int minweight[maxn]; //存此时的最小权值
对于weights[maxn][maxn]数组,其作用是保存两顶点之间的权值;
对于dots[maxn]数组,其作用是保存最小生成树中一个顶点对应连接的另一个节点编号;
对于minweight[maxn]数组,其作用是保存当前进入树中的顶点到未进入树中顶点的权值的最小值,同时如果置0则表示已经进树。
下面给出带有注释的代码(设顶点为从0开始排列)
int main()
{
int i,j,k n;
int infinity=999999;
int src=0;//设0顶点先进入树
/*读入数据省略,n为顶点个数,两顶点不相连权值置为无穷*/
for(i=0;i<n;i++){
minweight[i]=weights[src][i];//此时的最小值即为src到其他顶点的权值
dots[i]=src;//此时其他顶点都与src相连
}
minweight[src]=0;//置0进入树
for(i=1;i<n;i++){
min=infinity;
for(j=0,k=0;j<n;j++){
if(minweight[j]!=0&&minweight[j]<min){
min=minweight[j],k=j;
/*找到此时最小的权值*/
}
}
minweight[k];//该顶点进入树
for(j=0;j<n;j++){
if(minweight[j]!=0&&weights[k][j]<minweight[j]){
minweight[j]=weights[k][j];//更新最小权值
dots[j]=k;//k与j相连
}
}
}
}
至此结束