国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Dijkstra算法--單源最短路徑

2019-11-11 00:30:47
字體:
來源:轉載
供稿:網友

在http://blog.csdn.net/hacker_zhidian/article/details/54898064這一篇博客中總結了一下在求圖的最短路中的一個算法-Floyd算法,Floyd算法用于求圖的多源最短路徑(多源最短路徑:圖的所有頂點到其他頂點的最短路徑),時間復雜度和其他求最短路算法相比較高,如果一些題目只要求求單源最短路徑(單源最短路徑:圖的某個頂點到其他頂點的最短路徑)的話,Floyd算法顯然不是最好的選擇,那么今天我們來看一下另一個用于求單源最短路徑的算法:Dijkstra算法。

首先我們來看一個圖: 這里寫圖片描述 圖中共有A、B、C、D四個頂點,五條邊,假設我們現在要求頂點B到其他頂點的最短路徑,依據Dijkstra算法的原理:

首先我們先找到距離頂點B路徑最短的頂點,在這個圖中很明顯距離頂點B路徑最短的點為頂點D。之后,將頂點D做上訪問標記,并對圖中的所有頂點進行檢測,看看能否通過頂點D來縮短頂點B到其他頂點的路徑。很明顯,B–>D–>C(路徑為3)這條路的路徑小于B–>C(路徑為6)這條路的路徑,那么我們更新從頂點B到頂點C的最短路徑,頂點D的試探結束。我們可以將這個過程稱為“縮放”,現在,頂點D的“縮放”結束。之后我們繼續尋找距離頂點B路徑最短并且沒有被標記的頂點,現在距離頂點B路徑最短并且沒有被標記的頂點為頂點C(頂點D已經被標記了),同樣的重復“縮放”過程,直到圖中所有的頂點都被標記。

理解了上面的過程,我們就可以架構出大概的Dijkstra算法的代碼了:

/** n 代表圖的頂點總數* e[][] 代表圖的鄰接矩陣儲存* book[] 代表標記數組,標記頂點是否已經被選擇過* dis[] 數組儲存的是源點距離其他頂點的最短路徑*/for(int i = 1; i <= n - 1; i++) // 對除了頂點B以外的所有頂點進行“縮放”,所以是n-1次頂點縮放{ int min = inf; // inf 為無窮大 int u; // u為當前距離頂點B路徑最短的頂點 for(int j = 1; j <= n; j++) // 找到距離頂點B最短的頂點 { if(book[j] == 0 && dis[j] < min) { min = dis[j]; u = j; } } book[u] = 1; // 對要縮放的頂點進行標記 for(int k = 1; k <= n; k++) // 對這個距離頂點B最短的頂點進行縮放 { if(e[u][k] < inf) { if(dis[k] > dis[u] + e[u][k]) { dis[k] = dis[u] + e[u][k]; // 如果確實可以通過這個頂點的縮放來縮短最短路徑,那么更新最短路徑 } } }}

Ok,算法的核心代碼就是這些了,下面給出這個例子的完整代碼:

/** n 代表圖的頂點總數* e[][] 代表圖的鄰接矩陣儲存* book[] 代表標記數組,標記頂點是否已經被選擇過* dis[] 數組儲存的是源點距離其他頂點的最短路徑*/#include <iostream>using namespace std;const int N = 500;const int inf = 999999999;int e[N][N];int book[N];int dis[N];int main(){ int n, m, s; // 圖的頂點總數、邊的總數和源節點 cin >> n >> m>> s; for(int i = 1; i <= n; i++) { dis[i] = inf; // 初始化dis數組 for(int j = 1; j <= n; j++) { if(i == j) { e[i][j] = 0; } else { e[i][j] = inf; } } } int x, y, w; // 邊的信息 for(int i = 1; i <= m; i++) // 輸入邊 { cin >> x >> y >> w; e[x][y] = e[y][x] = w; } dis[s] = 0; for(int i = 1; i <= n - 1; i++) // 對除了源點以外的所有頂點進行“縮放”,所以是n-1次頂點縮放 { int min = inf; // inf 為無窮大 int u; // u為當前距離源點路徑最短的頂點 for(int j = 1; j <= n; j++) // 找到距離源點最短的頂點 { if(book[j] == 0 && dis[j] < min) { min = dis[j]; u = j; } } book[u] = 1; // 對要縮放的頂點進行標記 for(int k = 1; k <= n; k++) // 對這個距離源點最短的頂點進行縮放 { if(e[u][k] < inf) { if(dis[k] > dis[u] + e[u][k]) { dis[k] = dis[u] + e[u][k]; // 如果確實可以通過這個頂點的縮放來縮短最短路徑,那么更新最短路徑 } } } } for(int i = 1; i <= n; i++) // 輸出源點到其他頂點的最短路徑 { cout.width(-5); cout << dis[i] << " "; } cout << endl; return 0;}

接下來,我們將給出的例圖中的數據輸入并運行程序: 這里寫圖片描述 和預想的一樣,小伙伴們可以自己嘗試一下。 在這里,Dijkstra算法的時間復雜度為O(N^2),確實比Floyd算法小。當然,還有一點要注意,Dijkstra算法是不能解決具有負權邊的圖的。 如果博客中有什么不正確的地方,還請多多指點。 謝謝觀看。。。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 曲周县| 都兰县| 剑河县| 阿克苏市| 泸水县| 沙洋县| 长武县| 富蕴县| 嵊州市| 重庆市| 连山| 哈巴河县| 枣庄市| 桐乡市| 河北省| 思南县| 蚌埠市| 岚皋县| 余干县| 孟连| 图们市| 绥阳县| 金寨县| 庄浪县| 清苑县| 东至县| 新郑市| 贺州市| 玉门市| 岑巩县| 四川省| 改则县| 运城市| 漠河县| 阳东县| 兖州市| 孝义市| 清丰县| 两当县| 宝清县| 通渭县|