單源最短路徑的求法

2021-04-12 14:52:26 字數 2291 閱讀 6563

2.最短路徑

演算法思想:

設圖中有n個結點,設定乙個集會u,存放已經求出最短路徑的結點(初始時u中的元素是源點),v-u是尚未確定最短路徑的頂點的集合。每次從v-u集合中找這樣乙個結點best_jbest_ju集合中結點的鄰接點,到源點的距離最短(等於到父結點的距離加上父結點到源點的距離)。然後把該best_j置入u集合中,直到u=va.

標號法求解單源點最短路徑:

vara:array[1..maxn,1..maxn] of integer;

b:array[1..maxn] of integer; 

mark:array[1..maxn] of boolean;

procedure bhf;

varbest,best_j:integer;

begin

fillchar(mark,sizeof(mark),false);

mark[1]:=true; b[1]:=0;

repeat

best:=0;

for i:=1 to n do

if mark[i] then 

for j:=1 to n do

if (not mark[j]) and (a[i,j]>0) then 

if (best=0) or (b[i]+a[i,j]

因為b[1]=0

,所以best

的第乙個值是

b[i,j]值}

begin

best:=b[i]+a[i,j];  best_j:=j;

end;

if best>0 then begin

b[best_j]:=best

; mark[best_j]:=true;

end;

until best=0;

end;

總結:每次找

best_j

都要雙重迴圈,原因是沒有把未標號結點當前到源點的最短距離儲存起來,還有優化的空間。

c. dijkstra演算法:

vara:array[1..maxn,1..maxn] of integer;

b,pre:array[1..maxn] of integer; 

mark:array[1..maxn] of boolean;

procedure dijkstra(v0:integer);

begin

fillchar(mark,sizeof(mark),false);

for i:=1 to n do begin

d[i]:=a[v0,i];

if d[i]<>0 then pre[i]:=v0 else pre[i]:=0;

end;

mark[v0]:=true;

repeat   

min:=maxint; u:=0; 

for i:=1 to n do

if (not mark[i]) and (d[i]

begin

u:=i; min:=d[i];

end;

if u<>0 then begin

mark[u]:=true; 

for i:=1 to n do

if (not mark[i]) and (a[u,i]+d[u]

如果未標號的結點經過新標號的結點到源點的距離最短,則調整,這樣

d集合總是未標號結點到源點的最短距離

}begin

d[i]:=a[u,i]+d[u];

pre[i]:=u;

end;

end;

until u=0;

end;

單源最短路徑

include define max 999 define maxverts 10 typedef struct graph void chushi graph g void dij graph int key,int int int main for i 1 i g.numverts i dij ...

單源最短路徑

最優子結構 最短路徑的子路徑也是最短路徑,動態規劃和貪心演算法的乙個重要指標。環路 一條最短路徑不可能包含環路 1 環路權重為負,如果有一條環路權重為負,則不存在最短路徑 2 環路權重為零,如果包含該環路,則將該環路去掉即可 3 環路權重為正,去掉改環路可以得到更短的路徑,因此不可能是最短路徑 最短...

單源最短路徑

單源最短路徑問題,即在圖中求出給定頂點到其他任一頂點的最短路徑。1.最短路徑的最優子結構性質 該性質描述為 如果p i,j 是從頂點i到j的最短路徑,k和s是這條路徑上的乙個中間頂點,那麼p k,s 必定是從k到s的最短路徑。證明 假設p i,j 是從頂點i到j的最短路徑,則有p i,j p i,k...