王心远吧 关注:18贴子:329
  • 1回复贴,共1

Kruskal求图的次小生成树

只看楼主收藏回复

Kruskal求图的次小生成树  
 算法:先求MST。分别删除MST中的每条边再求MST。在所有结果中取最小,即为次小生成树。 
以边目录方式输出,输出第一行为MST,第二行是次小生成树。 

const maxm=250000; 
      maxn=500; 
var bg,ed,l:array[1..maxm] of longint; 
    can:array[1..maxm] of boolean; 
    first,tfirst,fa:array[1..maxn+1] of longint; 
    n,m,ans1,ans2,i:longint; 
procedure QuickSort(left,right:longint); 
var i,j,mid,t:longint; 
begin 
     i:=left; j:=right; mid:=l[(left+right)shr 1]; 
     repeat 
           while(l[i]<mid)do inc(i); 
           while(l[j]>mid)do dec(j); 
           if(i<=j)then 
           begin 
                t:=bg[i]; bg[i]:=bg[j]; bg[j]:=t; 
                t:=ed[i]; ed[i]:=ed[j]; ed[j]:=t; 
                t:=l[i]; l[i]:=l[j]; l[j]:=t; 
                inc(i); dec(j); 
           end; 
     until i>j; 
     if i<right then QuickSort(i,right); 
     if left<j then QuickSort(left,j); 
end; 
function find(x:longint):longint; 
var tx,tx2,temp:longint; 
begin 
     tx:=x; 
     while fa[tx]<>tx do tx:=fa[tx]; 
     tx2:=x; 
     while fa[tx2]<>tx do 
     begin 
          temp:=fa[tx2];fa[tx2]:=tx;tx2:=temp; 
     end; 
     find:=tx; 
end; 
procedure kruskal; 
var i,t,tx,ty:longint; 
begin 
     for i:=1 to n do fa[i]:=i; 
     i:=0;t:=0; 
     repeat 
     inc(i); 
     if can[i] then 
     begin 
          tx:=find(bg[i]);ty:=find(ed[i]); 
          if tx<>ty then 
          begin 
               inc(t);fa[tx]:=ty; 
               inc(ans1,l[i]); 
               first[t]:=i; 
          end; 
     end; 
     until (t=n-1) or (i=m); 
     if (i=m) and (t<n-1) then ans1:=-1; 
end; 
begin 
     randomize; 
     readln(n,m); 
     for i:=1 to m do readln(bg[i],ed[i],l[i]); 
     QuickSort(1,m); 
     fillchar(can,sizeof(can),true); 
     kruskal; 
     writeln('Cost: ',ans1); 
     ans2:=maxlongint; 
     tfirst:=first; 
     for i:=1 to n-1 do 
     begin 
          can[tfirst[i]]:=false; 
          ans1:=0; 
          kruskal; 
          if(ans1>-1)and(ans1<ans2) then ans2:=ans1; 
          can[tfirst[i]]:=true; 
     end; 
     if ans2=maxlongint then ans2:=-1; 
     writeln('Cost: ',ans2); 
end.  
 



1楼2007-05-22 22:08回复
    输入1 

    4 6 {4个顶点,6条边} 
    1 2 2 {顶点1到顶点2有一条权为2的边} 
    2 3 2 
    3 4 2 
    4 1 2 
    1 3 1 
    2 4 1 

    输出1 
    Cost: 4 
    Cost: 4 

    输入2 

    3 2 
    1 2 2 
    2 3 2 

    输出2 

    Cost: 4 
    Cost: -1 {不存在次小生成树}


    2楼2007-05-22 22:08
    回复