Prim:

算法步骤:

1.任意结点开始(不妨设为v1)构造最小生成树: 2.首先把这个结点(出发点)包括进生成树里, 3.然后在那些其一个端点已在生成树里、另一端点还未在生成树里的所有边中找出权最小的一条边, 4.并把这条边、包括不在生成树的另一端点包括进生成树, …。 5.依次类推,直至将所有结点都包括进生成树为止

Pascal的渣渣代码...

注:寻找最短的边那一步可以用堆优化,但那样还不如直接用Kruskal......

Reference:  http://www.nocow.cn/index.php/Prim%E7%AE%97%E6%B3%95

const vmax=1000;
var 
w:array[1..vmax,1..vmax] of longint;
i,j,k,v,e:longint;
w:存储邻接矩阵
v:结点数
e:边数

procedure prim(v0:longint);
var flag:array[1..vmax] of boolean;  //flag:表示是否在树中。true是, false否
      min,prevk,nextk:longint;
begin
 fillchar(flag,sizeof(flag),0);
 flag[v0]:=true;           //STEP2
 for i:=1 to v-1 do          //最小生成树中有v-1条边 ,所以外层循环需要v-1次        //STEP5
   begin
    min:=maxlongint;

    for k:=1 to v do  
      if flag[k] then  
        //寻找在最小生成树中的点  k:当前在最小生成树中的点
        for j:=1 to v do          //STEP3
          //寻找与(最小生成树中的点)的距离最短的点。
          // j:当前要找的不在最小生成树中的点 
          if (not flag[j]) and (w[k,j]<min) and (w[k,j]<>0) then
            紫色代码://判重:要找的点不能在最小生成树中
            红色代码://k与j必须相连!
            begin
            min:=w[k,j];
            nextk:=j;    
            prevk:=k;    
            //这条边从在最小生成树中的点出发 ,
            //扩展到当前不在最小生成树中的点。
            //prevk:=k,prevk为起点,在最小生成树中
            //nextk:=j,nextk为 终点,当前不在最小生成树中
            end;

    if min<>maxlongint then        
      //如果找到了nextk这样的可以从当前最小生成树中扩展出来
      //(可以进入最小生成树)的点
      begin
      flag[nextk]:=true;        //将nextk这样的点加入最小生成树    //STEP4
      writeln(prevk,‘ ’,nextk,‘ ’,min);           //输出这条边
      end;
   end;
end;


begin
fillchar(w,sizeof(w),0);
readln(v,e);
for k:=1 to e do
 begin
 read(i,j);
 readln(w[i,j]);
 w[j,i]:=w[i,j];
 end;

prim(1);       //STEP1

end.
View Code

相关文章: