在網圖和非網圖中,最短路徑的含義是不同的。由於非網圖它沒有邊上的權值,所謂的最短路徑,其實就是指兩頂點之間經過的邊數最少的路徑;而對於網圖來說,最短路徑,是指兩頂點之間經過的邊上權值之和最少的路徑,並且我們稱路徑上的第乙個頂點是源點,最後乙個頂點是終點。
這個演算法的思路就是:求整個圖的最短路徑(最優解,不一定唯一),轉化為求區域性最優解,以下面這圖為例:
求a到d的最短路徑,我們肉眼可以看出最短路徑是走a->b->d
或者a->c->d
,但這只是簡單的情況,那麼假如有幾十個點的情況,怎麼做呢?
我們可以將複雜的問題簡單化,分步求解:
複雜的不會求,那麼這個夠簡單了吧,a到b的距離,只有1條邊,很明顯就是1
那這個呢?a到d的最短距離,a到d有2條路可以走,分別是a->b->d
和a->d
,也就是1+2
和4
做比較。
那麼n個結點呢?一樣的,就是每次都拿到源結點,然後找到所有能到達目的結點的路徑,然後比較所有路徑的長度;因為我們一開始並不知道走哪條路能到達目的結點,所以我們需要遍歷整個圖所有結點;而計算到目的結點的最優解,就變成了每一次都計算出到v(v指任意結點)結點的最短路徑,每一次的區域性最短路徑(最優解),合起來就變成了最終的最短路徑(最優解)。這就是迪傑斯特拉演算法的靈魂。
#define maxvex 9
#define infinity 65535
typedef
int pathmatirx[maxvex]
;//用於儲存最短路徑下標的陣列
typedef
int shortpathtable[maxvex]
;//用於儲存到各點最短路徑的權值和
/* dijkstra演算法,求有向圖g的v0頂點到其餘頂點v最短路徑p[v]及帶權長度d[v],p[v]的值為前驅頂點下標,d[v]表示v0到v的最短路徑長度和 */
void
shortestpath_dijkstra
(mgraph g,
int v0, pathmatirx *p, shortpathtable *d)
(*d)
[v0]=0
;//v0至v0路徑為0
final[v0]=1
;//v0至v0不需要求路徑
/* 開始主迴圈,每次求得v0到某個v頂點的最短路徑 */
for(v=
1;vfinal[k]=1
;//將目前找到的最近的頂點置為1
for(w=
0;w}}
通過迪傑斯特拉演算法解決了從某個源點到其餘各頂點的最短路徑問題。從迴圈巢狀可以很容易得到此演算法的時間複雜度為o(n^2)
,儘管有同學覺得,可不可以只找到從源點到某乙個特定終點的最短路徑,其實這個問題和求源點到其他所有頂點的最短路徑一樣複雜,時間複雜度依然是o(n^2)
。
typedef
int pathmatirx[maxvex]
[maxvex]
;typedef
int shortpathtable[maxvex]
[maxvex]
;/* floyd演算法,求網圖g中各頂點v到其餘頂點w最短路徑p[v][w]及帶權長度d[v][w] */
void
shortestpath_floyd
(mgraph g, pathmatirx *p, shortedpathtable* d)
}for
(k=0
;k++k)}}
}}
求最短路徑的顯示**
for
(v=0
;v++v)
printf
("->%d\n"
, w)
;//列印終點
}printf
("\n");
}
如果面臨需要求所有頂點到所有頂點的最短路徑問題時,弗洛伊德(floyd)演算法應該是不錯的選擇。
下面用迪傑斯特拉演算法做簡單實現
//儲存最短路徑下標的陣列
typedef
int shortpathtable;
//用於儲存到各點最短路徑的權值和
typedef
char vextype;
typedef
int edgetype;
struct mgraph
;void
initmgraph
(mgraph* g)
printf
("輸入邊和權值:\n");
for(i=
0;inumedges;i++)}
/* dijkstra演算法,求頂點v0到其餘頂點v最短路徑p[v]及帶權長度d[v],
p[v]的值為前驅頂點下標,d[v]表示v0到v的最短路徑長度和 */
void
shortestpath_dijkstra
(mgraph* g,
int v0, pathmatirx* p, shortpathtable* d)
d[v0]=0
;//表示v0結點到本身權值為0
final[v0]=1
;//標誌第乙個結點已經訪問過了
for(v=
1;vnumvertexes;v++)}
final[k]=1
;//得到最小邊所對應的尾結點,標識為已經是最短邊集合的點
for(w=
0;wnumvertexes;w++)}
}}intmain()
road[i]
= v0;
//將路徑的最後乙個結點設定為v0
//列印
printf
("最短路徑和為:%d\n"
,d[v]);
printf
("結點%d到%d的最短路徑為:"
迪傑斯特拉最短路徑
問題描述 在帶權有向圖g中,給定乙個源點v,求從v到g中的其餘各頂點的最短路徑問題,叫做單源點的最短路徑問題。在常用的單源點最短路徑演算法中,迪傑斯特拉演算法是最為常用的一種,是一種按照路徑長度遞增的次序產生最短路徑的演算法。在本題中,讀入乙個有向圖的帶權鄰接矩陣 即陣列表示 建立有向圖並按照以上描...
最短路 (迪傑斯特拉)
a 最短路 crawling in process.crawling failed time limit 1000msmemory limit 32768kb64bit io format i64d i64u submit status practice hdu 2544 description 在...
最短路徑 迪傑斯特拉演算法
例如,要求下圖v0到v8的最短路徑 所以我們可以找到這樣的一條最短路徑 下面是他的鄰接矩陣 偽 如下 define maxvex 9 define infinity 65535 typedef int patharc maxvex 用於儲存最短路徑下標的陣列 typedef int shortpat...