單源最短路徑問題,即在圖中求出給定頂點到其它任一頂點的最短路徑。在弄清楚如何求算單源最短路徑問題之前,必須弄清楚最短路徑的最優子結構性質。
一.最短路徑的最優子結構性質
該性質描述為:如果p(i,j)=是從頂點i到j的最短路徑,k和s是這條路徑上的乙個中間頂點,那麼p(k,s)必定是從k到s的最短路徑。下面證明該性質的正確性。
假設p(i,j)=是從頂點i到j的最短路徑,則有p(i,j)=p(i,k)+p(k,s)+p(s,j)。而p(k,s)不是從k到s的最短距離,那麼必定存在另一條從k到s的最短路徑p'(k,s),那麼p'(i,j)=p(i,k)+p'(k,s)+p(s,j)二.dijkstra演算法
由上述性質可知,如果存在一條從i到j的最短路徑(vi.....vk,vj),vk是vj前面的一頂點。那麼(vi...vk)也必定是從i到k的最短路徑。為了求出最短路徑,dijkstra就提出了以最短路徑長度遞增,逐次生成最短路徑的演算法。譬如對於源頂點v0,首先選擇其直接相鄰的頂點中長度最短的頂點vi,那麼當前已知可得從v0到達vj頂點的最短距離dist[j]=min。根據這種思路,
假設存在g=,源頂點為v0,u=,dist[i]記錄v0到i的最短距離,path[i]記錄從v0到i路徑上的i前面的乙個頂點。
1.從v-u中選擇使dist[i]值最小的頂點i,將i加入到u中;
2.更新與i直接相鄰頂點的dist值。(dist[j]=min)
3.知道u=v,停止。
**實現:
/*測試資料:dijkstra求單源最短路徑 2010.8.26
*/#include
#include
#define m 100
#define n 100
using
namespace
std;
typedef
struct
node
mgraph;
void dijkstrapath(mgraph g,int *dist,int *path,int v0) //
v0表示源頂點
else
visited[i]=false
; path[v0]=v0;
dist[v0]=0
; }
visited[v0]=true
;
for(i=1;i//
迴圈擴充套件n-1次
} visited[u]=true
;
for(k=0;k//
更新dist陣列的值和路徑的值
}
}
}void showpath(int *path,int v,int v0) //
列印最短路徑上的各個頂點
s.push(v);
while(!s.empty())
} int main(int argc, char *argv)
cin>>v0; //
輸入源頂點
dijkstrapath(g,dist,path,v0);
for(i=0;i)}}
return0;
}
執行結果:
Dijkstra 單源最短路徑
演算法思想 輔助陣列dis i 表示當前源頂點到i的最短路徑。dis i 在程式未結束前,類似於動態規劃,可更新以取得最小值 陣列path用來記錄路徑 首先初始化令dis i 為edge v0 i v0為源頂點 然後選擇離源頂點最小的路徑,加入到構造最短路徑的點集合中,然後看是否可以更新dis i ...
Dijkstra 單源最短路徑
演算法思想 輔助陣列dis i 表示當前源頂點到i的最短路徑。dis i 在程式未結束前,類似於動態規劃,可更新以取得最小值 陣列path用來記錄路徑 首先初始化令dis i 為edge v0 i v0為源頂點 然後選擇離源頂點最小的路徑,加入到構造最短路徑的點集合中,然後看是否可以更新dis i ...
Dijkstra單源最短路徑
dijkstra單源最短路徑 給定乙個帶權有向圖g v,e 其中每條邊的權是乙個非負實數。另外,還給定 v 中的乙個頂點,稱為源。現在我們要計算從源到所有其他各頂點的最短路徑長度。這裡的長度是指路上各邊權之和。這個問題通常稱為單源最短路徑問題。下面給出兩個計算單源最短路徑的模板。dijkstra 簡...