Dijkstra算法樹解決有向圖G=(V,E)上帶權的單源最短路徑問題,可是要求全部邊的權值非負。html
解題思路:ios
V表示有向圖的全部頂點集合,S表示那麼一些頂點結合,從源點s到該集合中的頂點的最終最短路徑的權值(程序中用dist[i]表示)已經肯定。算法反覆選擇具備最短路徑估計的頂點u 屬於 V-S(即未肯定最短路徑的點,程序中finish[i]=false的點),並將u加入到S中(用finish[i]=true表示),最後對u的全部輸出邊進行鬆弛。算法
程序實現:spa
輸入數據:.net
5 7code
0 1 100htm
0 2 30blog
0 4 10ip
2 1 60ci
2 3 60
3 1 10
4 3 50
/************************************************************************* > File Name: Dijkstra.cpp > Author: He Xingjie > Mail: gxmshxj@163.com > Created Time: 2014年06月07日 星期六 22時12分43秒 > Description: ************************************************************************/ #include<iostream> #include<cstdio> using namespace std; #define INF 99999 //map矩陣記錄路徑圖,dist[i]表示源點到節點 //i的最短路徑,finish[i]表示節點i找到最短路徑 //path[i]=j表示從源節點到i節點的最短路徑要通過j int map[100][100], dist[100], finish[100]; int path[100]; void Dijkstra(int s, int n) { /* *s爲源點,n爲節點的個數 *當finish[i]=true時,dist[i] *爲s到i的最短路徑 *假設S爲已求得最短路徑的終點集合 *V爲全部節點的集合 */ int i, j, v, k; //初始化dist[i] for (i=1; i<n; i++) { dist[i] = map[s][i]; if (dist[i] < INF) path[i] = s; } //初始化源節點 finish[s] = true; dist[s] = 0; for (i=1; i<n; i++) //總共有n-1個節點 { int min = INF; for (j=0; j<n; j++) { //從V-S中(沒有找到最短路徑的集合)尋找離源節點 //距離最近的點 if (!finish[j] && dist[j] < min) { v = j; min = dist[j]; } } //找到最短路徑 finish[v] = true; //把節點v加入到S中 //鬆弛(Relax) for (k=0; k<n; k++) { if (!finish[k] && map[v][k] != INF) if (dist[k] > dist[v] + map[v][k]) { dist[k] = dist[v] + map[v][k]; path[k] = v; } } } } void PrintPath(int k) { if (k == 0) { printf("%d", k); return; } PrintPath(path[k]); printf("->%d", k); } void PrintMap(int n) { int i, j; //輸出矩陣 for (i=0; i<n; i++) { for (j=0; j<n; j++) { if (map[i][j] == INF) printf("INF "); else printf("%d ", map[i][j]); } printf("\n"); } } int main() { int n, m, i, j; freopen("input.txt", "r", stdin); cin>>n>>m; //n是頂點數,m是邊數 //初始化 for (i=0; i<n; i++) { finish[i] = false; for (j=0; j<n; j++) map[i][j] = INF; } //輸入 for(int i=1; i<=m; i++) { int i,j; cin>>i>>j; cin>>map[i][j]; } /* *PrintMap(n); */ Dijkstra(0, n); for (i=1; i<n; i++) { printf("Path: "); PrintPath(i); printf(" Dist:%d\n", dist[i]); } return 0; }
參考:
http://www.cnblogs.com/dolphin0520/archive/2011/08/26/2155202.html