1、問題描述
給定帶權有向圖g =(v,e),其中每條邊的權是非負實數。另外,還給定v中的乙個頂點,稱為源。現在要計算從源到所有其他各頂點的最短路長度。這裡路的長度是指路上各邊權之和。這個問題通常稱為單源最短路徑問題。
2、dijkstra演算法
dijkstra演算法是解單源最短路徑問題的貪心演算法。
其基本思想是,設定頂點集合s並不斷地作貪心選擇來擴充這個集合。乙個頂點屬於集合s當且僅當從源到該頂點的最短路徑長度已知。初始時,s中僅含有源。設u是g的某乙個頂點,把從源到u且中間只經過s中頂點的路稱為從源到u的特殊路徑,並用陣列dist記錄當前每個頂點所對應的最短特殊路徑長度。dijkstra演算法每次從v-s中取出具有最短特殊路長度的頂點u,將u新增到s中,同時對陣列dist作必要的修改。一旦s包含了所有v中頂點,dist就記錄了從源到所有其他頂點之間的最短路徑長度。
dijkstra演算法可描述如下,其中輸入帶權有向圖是g=(v,e),v=,頂點v是源。c是乙個二維陣列,c[i][j]表示邊(i,j)的權。當(i,j)不屬於e時,c[i][j]是乙個大數。dist[i]表示當前從源到頂點i的最短特殊路徑長度。在dijkstra演算法中做貪心選擇時,實際上是考慮當s新增u之後,可能出現一條到頂點的新的特殊路,如果這條新特殊路是先經過老的s到達頂點u,然後從u經過一條邊直接到達頂點i,則這種路的最短長度是dist[u]+c[u][i]。如果
dist[u]+c[u][i]。步驟如下:
(1) 用帶權的鄰接矩陣c來表示帶權有向圖, c[i][j]表示弧上的權值。設s為已知最短路徑的終點的集合,它的初始狀態為空集。從源點v經過s到圖上其餘各點vi的當前最短路徑長度的初值為:dist[i]=c[v][i], vi屬於v.
(2) 選擇vu, 使得dist[u]=min,vj就是長度最短的最短路徑的終點。令s=s u .
(3) 修改從v到集合v-s上任一頂點vi的當前最短路徑長度:如果 dist[u]+c[u][j]< dist[j] 則修改 dist[j]= dist[u]+c[u][j].
(4) 重複操作(2),(3)共n-1次.
演算法具體實現如下
#include
#include
#include
using namespace std;
#define n 5
#define m 10000
template
void dijkstra(int n,int v,type dist,int prev,type c[n+1])
else
} dist[v] = 0;
s[v] = true;
for(int i=1; i"cout<} dijkstra(n,v,dist,prev,c);
for(int j=2; j<=n; j++)
return 0;
}
單源最短路徑
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...