#返回上一級
@author: 張海拔
@update: 2015-03-11
@link:
dijkstra演算法
總的來說:演算法從開始節點,按照總路徑權值非遞減的順序去搜尋所有路徑,直到發現指定的終止節點或發現全部節點為止。
——我們先看看演算法的步驟:
演算法是遞推的
先設d[begin] = 0, d[others] = inf
for [0, n)
1、未標記的節點中,選出當前d值最小的 (最快logn效率)
2、標記節點i
3、據節點i,若d[i] + w[i][j] < d[j],則更新d[j](d[j]可能變小,o(n)效率)
——我們再看看為什麼這樣做
迴圈每一步能確定以i節點為終點的最短路徑(定義這種節點為:「最短路終點」)
而且很關鍵的一點是,這個最短路徑終點的d值是最小遞增或者說一定是非遞減的
也就是上面說的「按照總路徑權值非遞減的順序去搜尋所有路徑」
另外,d值的意義是:當前狀態下,以該節點為終點的最短路徑長度
假定a是起點,顯然是a為終點的最短路徑,d值是0
後續步驟中都是從已確定最短路終點集合中,遞推出下乙個最短路終點
想想最簡單的情況
a只能到b和c和d,ab邊長5,ac邊長3,ad邊長4
當前最短路終點集合只有a,集合一步可達的節點有b c d
它們目前的d值分別是5 3 4
把最小d值的c納入最短路終點集合,因為它的d值無法變得更小,也就是說從當前狀態往後這個節點的d值都是確定的
為什麼呢?
把c納入最短路終點集合,若cb邊長是1,則會修改b的d值變為4,所以非最小值d值的節點,其d值可能會變得更小
反過來,若納入其它任何節點到最短路終點集合,都不可能使其d值變得更小
因為不會出現 dnonmin + edge < dmin 的情況
後續情況同理類推
所以原理就是:
根據已經最短路終點集合來遞推下乙個最短路終點
過程使最短路終點集合一步可達的那些節點的d值不斷減小
直到某節點d值無法減小,則納入最短路終點集合
**實現:
1/*2*author: zhanghaiba
3*date: 2014-1-10
4*file: dijkstra.c5*
6*dijkstra's algorithm demo7*/
89 #include 10 #include
11#define n 512
12#define inf 0x7fffffff;
1314
void dijkstra(int, int
);15
void print_path(int, int
);16
void set_mat(int
);17
void show_mat(int
);18
19int
mat[n][n];
20int
vis[n];
21int
d[n];
22int
par[n];
2324
intmain(void)
2540
41void dijkstra(int begin, int
n)4269}
70}7172
void print_path(int begin, int
i)73
7879
void set_mat(int
n)80
8788
void show_mat(int
n)89
測試用例
輸入:5
0 100 0 30 10
0 0 0 60 0
0 10 0 0 0
0 0 20 0 0
0 0 50 0 0
輸出0 3 2 1
60#返回上一級
單源最短路 Dijkstra演算法
前提 沒有負邊 如果有負邊,可以用此方法檢查是否有負圈 const max v max v 表示邊的權重值 d max v 儲存從起點到每個點的總權重值 bool used max v 表示當前點是否已經訪問完畢 思想 找到乙個已經確定最短距離的點,更新跟它相鄰的點,之後這個點就不用關心了。起點最短...
單源最短路演算法 Dijkstra
dijkstra演算法是單源最短路演算法,可以求解不帶負權邊的圖中,從源點s到其它所有點的最短路。時間複雜度近似o n 2 可以用堆優化。一般用鄰接表,也可用鄰接矩陣。在稠密圖上會有較好的效能表現。include include using namespace std int s,t,n,m,las...
單源最短路 Dijkstra演算法
本文 自王陸的文字,僅作學習使用。dijkstra 迪傑斯特拉 演算法是典型的單源最短路徑演算法,用於計算乙個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。問題描述 在無向圖 g v,e 中,假設每條邊 e i 的長度為 w i 找到由頂點 v0 到...