最小生成树

[复制链接]
发表于 2023-12-30 10:16:17 | 显示全部楼层 |阅读模式

1.最小生成树
A.Prim算法:
  procedure prim(v0:integer);
    var
      lowcost,closest:array[1..maxn] of integer;
i,j,k,min:integer;
    begin
      for i:=1 to n do begin
  lowcost:=cost[v0,i];
  closest:=v0;
  end;
for i:=1 to n-1 do begin
  {寻找离生成树最近的未加入顶点k}
  min:=maxlongint;
  for j:=1 to n do
    if (lowcost[j]<min) and (lowcost[j]<>0) then begin
    min:=lowcost[j];
    k:=j;
    end;
  lowcost[k]:=0; {将顶点k加入生成树}
    {生成树中增加一条新的边k到closest[k]}
  {修正各点的lowcost和closest值}
  for j:=1 to n do
    if cost[k,j]<lwocost[j] then begin
    lowcost[j]:=cost[k,j];
    closest[j]:=k;
    end;
  end;
end;{prim}
B.Kruskal算法:(贪心)
按权值递增顺序删去图中的边,若不形成回路则将此边加入最小生成树。
function find(v:integer):integer; {返回顶点v所在的集合}
var i:integer;
begin
  i:=1;
  while (i<=n) and (not v in vset) do inc(i);
  if i<=n then find:=i else find:=0;
end;
procedure kruskal;
var
  tot,i,j:integer;
begin
  for i:=1 to n do vset:=;{初始化定义n个集合,第I个集合包含一个元素I}
p:=n-1; q:=1; tot:=0; {p为尚待加入的边数,q为边集指针}
sort;
{对所有边按权值递增排序,存于e[I]中,e[I].v1与e[I].v2为边I所连接的两个顶点的序号,e[I].len为第I条边的长度}
  while p>0 do begin
    i:=find(e[q].v1);j:=find(e[q].v2);
    if i<>j then begin
    inc(tot,e[q].len);
    vset:=vset+vset[j];vset[j]:=[];
    dec(p);
    end;
    inc(q);
  end;
  writeln(tot);
end;

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表