2.最短路徑
演算法思想:
設圖中有n個結點,設定乙個集會u,存放已經求出最短路徑的結點(初始時u中的元素是源點),v-u是尚未確定最短路徑的頂點的集合。每次從v-u集合中找這樣乙個結點best_j:best_j是u集合中結點的鄰接點,到源點的距離最短(等於到父結點的距離加上父結點到源點的距離)。然後把該best_j置入u集合中,直到u=v。a.
標號法求解單源點最短路徑:
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...