acwing 849. Dijkstra求最短路 I
阿新 • • 發佈:2022-03-01
目錄
題目描述
給定一個 nn 個點 mm 條邊的有向圖,圖中可能存在重邊和自環,所有邊權均為正值。
請你求出 11 號點到 nn 號點的最短距離,如果無法從 11 號點走到 nn 號點,則輸出 −1−1。
輸入格式
第一行包含整數 nn 和 mm。
接下來 mm 行每行包含三個整數 x,y,zx,y,z,表示存在一條從點 xx 到點 yy 的有向邊,邊長為 zz。
輸出格式
輸出一個整數,表示 11 號點到 nn 號點的最短距離。
如果路徑不存在,則輸出 −1−1。
資料範圍
1≤n≤5001≤n≤500,
1≤m≤1051≤m≤105,
圖中涉及邊長均不超過10000。輸入樣例:
3 3 1 2 2 2 3 1 1 3 4
輸出樣例:
3
演算法求解
分析
模板
注意初始化的時候,初始化為正無窮
迴圈n-1次,然後每次確定一個點的最短距離
程式碼
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int INF = 0x3f3f3f3f; const int N = 510; int g[N][N]; // 用鄰接矩陣存圖 int st[N];// st[i] = true 表示i點的最短距離已經確定了 int dist[N]; // 存從1到每個點的最短距離 int n, m; // 返回從1到n的最短距離 int dijkstra() { // 初始化從1到所有點距離為正無窮 memset(dist, 0x3f, sizeof dist); dist[1] = 0; // 迴圈n-1次每次取未確定的點裡面距離最小的 for(int i = 0; i < n-1; i++) { // 從沒確定的點裡面選一個最小的值 t int t = -1; for(int i = 1; i <= n; i++) if(!st[i] && (t == -1 || dist[i] < dist[t])) t = i; // 跟新t指向節點的最短距離 for(int i = 1; i <= n; i++) // dist[i] = min(dist[i], dist[t] + g[t][i]); if(!st[i] && dist[i] > dist[t] + g[t][i]) dist[i] = dist[t] + g[t][i]; st[t] = true; //確定了一個點的最短距離 } if(dist[n] == INF) return -1; else return dist[n]; } int main() { // 初始化所有點之間邊權為無窮大 memset(g, 0x3f, sizeof g); scanf("%d%d", &n, &m); while(m--) { int a, b, c; scanf("%d%d%d", &a, &b, &c); g[a][b] = min(g[a][b], c); // 有重邊的話選小的那個 } int t = dijkstra(); printf("%d\n", t); return 0; }