Dijkstra求最短路(樸素Dijkstra演算法)
阿新 • • 發佈:2021-08-04
樸素Dijkstra演算法
集合S:存當前已經確定最短距離的點
一、初始化dist[1] = 0
, 其餘 dist[i] = 0x3f
二、for i : 0 ~~~ n, 有n個點,每迴圈一次就確定一輪最短距離
1、找到集合s以外的距離最近的點t
2、把t存入s中
3、用t來更新其他距離的點
dist[x] = dist[t] + w(邊權)
849. Dijkstra求最短路 I
給定一個 n
個點 m
條邊的有向圖,圖中可能存在重邊和自環,所有邊權均為正值。
請你求出 1
號點到 n
號點的最短距離,如果無法從 1
號點走到 n
號點,則輸出 −1
輸入格式
第一行包含整數 n
和 m
接下來 m
行每行包含三個整數 x,y,z
,表示存在一條從點 x
到點 y
的有向邊,邊長為 z
輸出格式
輸出一個整數,表示 1
號點到 n
號點的最短距離。
如果路徑不存在,則輸出 −1
資料範圍
1≤n≤500
1≤m≤105
圖中涉及邊長均不超過10000。
輸入樣例:
3 3
1 2 2
2 3 1
1 3 4
輸出樣例:
3
程式碼實現:
#include <bits/stdc++.h> using namespace std; const int N = 510; int g[N][N]; //鄰接表來存有向圖的邊長 int dist[N]; bool st[N]; //判斷這個點是否已經被確定為最短距離,即集合S int m, n; int Dijkstra(){ memset(dist, 0x3f, sizeof dist); dist[1] = 0; for(int i = 1; i <= n; i ++){ //有n個點,要進行n次迭代,每迭代一次就可以確定一個輪最短距離 int t = -1; // t表示正在訪問的點 for(int j = 1; j <= n; j ++){ if(!st[j] && (t == -1 || dist[t] > dist[j])){ //dist[t] > dist[j]表示t不是最短距離,所以讓t = j t = j; //找到未訪問過且距離最短的點 } } st[t] = true; for(int j = 1; j <= n; j ++){ dist[j] = min(dist[j], dist[t] + g[t][j]); //取1號點到j號點距離與1到t再到j的最短距離 } } if(dist[n] == 0x3f3f3f3f) return -1; else return dist[n]; } int main(){ cin >> n >> m; memset(g, 0x3f, sizeof g); int x, y, z; for(int i = 0; i < m; i ++){ cin >> x >> y >> z; g[x][y] = min(g[x][y], z); //有可能存在重邊,所以只要取最短的邊就好 } cout << Dijkstra() << endl; return 0; }