最小树的算法
谁能给我解释一下有关digkstra的算法!!!!!!!!!!!谢谢啦!
2008-08-04 10:09
程序代码:
function Dijkstra: TKey;
var
i: TIndex;
Cur, Ptr: TIndex;
Node: PFibonacciNode;
Heap: TFibonacciHeap;
begin
Heap.Create(N);
for i := 1 to N do
begin
Check[i] := false;
Heap.Insert(i, InfiniteValue);
Dist[i] := InfiniteValue;
end;
Heap.DecreaseKey(S, 0);
Dist[S] := 0;
while not Check[T] do
begin
Node := Heap.Minimum;
if Node = nil then Break;
Cur := Node^.Index;
Check[Cur] := true;
Heap.DeleteMin;
Ptr := Last[Cur];
while Ptr > 0 do
begin
with Edge[Ptr] do
if not Check[Adj] and (Dist[Adj] > Dist[Cur] + Weight) then
begin
Dist[Adj] := Dist[Cur] + Weight;
Heap.DecreaseKey(Adj, Dist[Adj]);
end;
Ptr := Edge[Ptr].Prev;
end;
end;
Result := Dist[T];
Heap.Destory;
end;
function Dijkstra2: TKey;
var
i: TIndex;
Cur, Ptr: TIndex;
Node: PBinaryNode;
Heap: TBinaryHeap;
begin
Heap.Create(N);
for i := 1 to N do
begin
Check[i] := false;
Heap.Insert(i, InfiniteValue);
Dist[i] := InfiniteValue;
end;
Heap.DecreaseKey(S, 0);
Dist[S] := 0;
while not Check[T] do
begin
Node := Heap.Minimum;
if Node = nil then Break;
Cur := Node^.Index;
Check[Cur] := true;
Heap.DeleteMin;
Ptr := Last[Cur];
while Ptr > 0 do
begin
with Edge[Ptr] do
if not Check[Adj] and (Dist[Adj] > Dist[Cur] + Weight) then
begin
Dist[Adj] := Dist[Cur] + Weight;
Heap.DecreaseKey(Adj, Dist[Adj]);
end;
Ptr := Edge[Ptr].Prev;
end;
end;
Result := Dist[T];
Heap.Destory;
end;
function Dijkstra3: TKey;
var
i: TIndex;
Cur, Ptr: TIndex;
Node: PPairNode;
Heap: TPairHeap;
begin
Heap.Create(N);
for i := 1 to N do
begin
Check[i] := false;
Heap.Insert(i, InfiniteValue);
Dist[i] := InfiniteValue;
end;
Heap.DecreaseKey(S, 0);
Dist[S] := 0;
while not Check[T] do
begin
Node := Heap.Minimum;
if Node = nil then Break;
Cur := Node^.Index;
Check[Cur] := true;
Heap.DeleteMin;
Ptr := Last[Cur];
while Ptr > 0 do
begin
with Edge[Ptr] do
if not Check[Adj] and (Dist[Adj] > Dist[Cur] + Weight) then
begin
Dist[Adj] := Dist[Cur] + Weight;
Heap.DecreaseKey(Adj, Dist[Adj]);
end;
Ptr := Edge[Ptr].Prev;
end;
end;
Result := Dist[T];
Heap.Destory;
end;
程序代码:
{
单源最短路径的Dijkstra算法。
使用二叉堆挑选
总复杂度O((e+v)logv)
}
const
maxn=100;
type
link=^node; //邻接表类型
node=record
v,w :integer;
next :link;
end;
htype=record //堆节点
v,d,p :integer;
end;
var
n,s,hl :integer; //顶点数;源点;堆长度
heap :array[0..maxn]of htype;
hpos :array[1..maxn]of integer; //hpos[v]:顶点v在堆中的位置
g :array[1..maxn]of link; //邻接表
procedure insert(u,v,w:integer); //将权值为w的边(u,v)插入到邻接表
var
x :link;
begin
new(x);
x^.v:=v; x^.w:=w;
x^.next:=g[u]; g[u]:=x;
end;
procedure init; //初始化
var
u,v,w :integer;
begin
assign(input,'g.in');reset(input);
readln(n,s);
while not eof do
begin
readln(u,v,w);
insert(u,v,w);insert(v,u,w);
end;
end;
procedure swap(a,b:integer); //交换堆中下标为a,b的节点
begin
heap[0]:=heap[a];heap[a]:=heap[b];heap[b]:=heap[0];
hpos[heap[a].v]:=a;hpos[heap[b].v]:=b;
end;
procedure decrease(i:integer); //减小键值并恢复堆性质
begin
while (i<>1)and(heap[i].d<heap[i div 2].d) do
begin
swap(i,i div 2);
i:=i div 2;
end;
end;
procedure heapfy; //恢复堆性质
var
i :integer;
begin
i:=2;
while i<=hl do
begin
if(i<hl)and(heap[i+1].d<heap[i].d) then inc(i);
if heap[i].d<heap[i div 2].d then
begin
swap(i,i div 2);
i:=i*2;
end
else break
end;
end;
procedure relax(u,v,w:integer); //松弛操作
begin
if w+heap[hpos[u]].d<heap[hpos[v]].d then
begin
heap[hpos[v]].p:=u;
heap[hpos[v]].d:=w+heap[hpos[u]].d;
decrease(hpos[v]);
end;
end;
procedure dijkstra; //主过程
var
u :integer;
p :link;
begin
for u:=1 to n do //初始化堆
begin
heap[u].v:=u;
heap[u].d:=maxint;
hpos[u]:=u;
end;
heap[s].p:=s;heap[s].d:=0;swap(1,s);
hl:=n;
while hl>0 do
begin
u:=heap[1].v;
swap(1,hl);dec(hl);heapfy; //将堆的根节点移出堆并恢复堆性质
p:=g[u];
while p<>nil do
begin
if hpos[p^.v]<=hl then relax(u,p^.v,p^.w); //对与u邻接且在堆中的顶点进行松弛操作
p:=p^.next;
end;
end;
end;
procedure path(i:integer);
begin
if heap[hpos[i]].p<>s then path(heap[hpos[i]].p);
write('-->',i);
end;
procedure show;
var
i :integer;
begin
for i:=1 to n do
begin
write(i:3,':',heap[hpos[i]].d:3,':',s);
path(i); //递归输出路径
writeln;
end
end;
{==========main===========}
begin
init;
dijkstra;
show;
end.
注:程序使用二叉堆
2008-08-04 11:58
2008-08-04 11:59
2008-08-04 14:46
2008-08-04 15:14