【藍橋杯】ALGO-5 最短路
- 2019 年 11 月 13 日
- 筆記
版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/weixin_42449444/article/details/102962166
題目描述:
給定一個n個頂點,m條邊的有向圖(其中某些邊權可能為負,但保證沒有負環)。請你計算從1號點到其他點的最短路(頂點從1到n編號)。
輸入描述:
第一行兩個整數n, m。接下來的m行,每行有三個整數u, v, l,表示u到v有一條長度為l的邊。(1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000),保證從任意頂點都能到達其他所有頂點。
輸出描述:
輸出共n-1行,第i行表示1號點到i+1號點的最短路。
輸入樣例:
3 3 1 2 -1 2 3 -1 3 1 2
輸出樣例:
-1 -2
解題思路:
Dijkstra演算法無法判斷含負權邊的圖的最短路,Floyd演算法時間複雜度為O(n³),故均不考慮。這裡用Bellman-Ford演算法,它能在存在負權邊的情況下解決單源點最短路徑問題。
AC程式碼:
#include <bits/stdc++.h> using namespace std; #define Up(i,a,b) for(int i = a; i <= b; i++) #define ms(a,x) memset(a,x,sizeof(a)) const int INF = 0x3f3f3f3f; const int maxn = 200001; int u[maxn],v[maxn],w[maxn]; int d[maxn]; //記錄起點1到各點的最短距離 int main() { ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); ms(d,INF); //初始化圖的資訊 d[1] = 0; //1到自身的距離為0 int n,m; //頂點數n,邊數m cin >> n >> m; Up(i,1,m) { cin >> u[i] >> v[i] >> w[i]; } Up(i,1,n-1) { bool flag = false; Up(j,1,m) { if(d[v[j]] > d[u[j]]+w[j]) { d[v[j]] = d[u[j]]+w[j]; //更新最短路 flag = true; } } if(!flag) break; //若不再更新最短路,提前退出循環 } Up(i,2,n) { cout << d[i] << endl; } return 0; }