1. 程式人生 > 實用技巧 >849.Dijkstra求最短路 I

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<iostream>
#include
<cstring> #include<algorithm> using namespace std; const int N = 510; int n, m; int g[N][N], dist[N]; //g儲存鄰接矩陣 dist儲存每個點到起點的最短距離 bool st[N]; //判斷當前點是否鬆弛過 int Dijkstra() { memset(dist, 0x3f, sizeof dist); //儲存每個點到起點的距離是無窮 dist[1] = 0; //起點到自身的距離是0 for(int i = 0; i < n; i++) //
迭代n次找到距離起點最近的點 { int t = -1; //t=-1是為了確定起點 儲存當前訪問的點 for(int j = 1; j <= n; j ++) if(!st[j] && (t == -1 || dist[t] > dist[j])) //如果當前節點沒有被鬆弛 並且 該點大於當前儲存點到起點的距離 t = j; //就更新當前節點到起點的距離 st[t] = true; //標記該點已經鬆弛 for
(int j = 1; j <= n; j++) dist[j] = min(dist[j], dist[t] + g[t][j]); //這裡更新每個點到相鄰點的距離 } if(dist[n] == 0x3f3f3f3f) return -1; //如果不存在最短距離返回-1 0x3f3f3f3f即無窮 這裡需要4個位元組儲存所以要4個3f return dist[n]; //返回該點到點n的最短距離 } int main() { memset(g, 0x3f, sizeof g); scanf("%d%d", &n, &m); while(m -- ) { int x, y, z; scanf("%d%d%d", &x, &y, &z); g[x][y] = min(g[x][y], z); //如果存在重邊,那取權重較小的一條邊 } printf("%d\n", Dijkstra()); return 0; }
View Code

兩次迭代的時間複雜度是O(n²) 這裡可以通過手寫堆來優化更新節點這一過程 讓時間複雜度降低到O(mlogn)

還有需要修改的地方往後再補充(*^-^)ρ