藍橋杯演算法訓練 最短路---SPFA演算法(帶負邊的最短路處理)
阿新 • • 發佈:2019-01-02
演算法訓練 最短路
時間限制:1.0s 記憶體限制:256.0MB
問題描述
給定一個n個頂點,m條邊的有向圖(其中某些邊權可能為負,但保證沒有負環)。請你計算從1號點到其他點的最短路(頂點從1到n編號)。
輸入格式
第一行兩個整數n, m。
接下來的m行,每行有三個整數u, v, l,表示u到v有一條長度為l的邊。
輸出格式
共n-1行,第i行表示1號點到i+1號點的最短路。
樣例輸入
3 3
1 2 -1
2 3 -1
3 1 2
樣例輸出
-1
-2
資料規模與約定
對於10%的資料,n = 2,m = 2。
對於30%的資料,n <= 5,m <= 10。
對於100%的資料,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保證從任意頂點都能到達其他所有頂點。
第一次接觸接觸到求帶負邊的最短路,顯然之前的Dijkstra和Floyd都不能解決,接觸到了SPFA演算法...準備把之前的最短路題用SPFA寫一遍試試...
Code:
#include<iostream> #include<sstream> #include<cstdlib> #include<cmath> #include<cctype> #include<algorithm> #include<cstring> #include<cstdio> #include<map> #include<vector> #include<stack> #include<queue> #include<set> #include<list> #define mod 998244353 #define INF 0x3f3f3f3f #define Min 0xc0c0c0c0 #define mst(a) memset(a,0,sizeof(a)) #define f(i,a,b) for(int i=a;i<b;i++) using namespace std; typedef long long ll; static const int MAX_N = 2e6 + 5; static const double pi = acos(-1); typedef struct XNode{ int dot, weight; //點,邊權 struct XNode *next; //下一個可達點 }Node; //鄰接表 Node *nods[MAX_N]; //任意點的下一個可達點 int dis[MAX_N]; bool vis[MAX_N]; int n, m; void init(int u, int v, int w){ Node *p; p = (Node *)malloc(sizeof(Node));//動態陣列 p ->dot = v; p ->weight = w; p ->next = nods[u]; //nods是一個指向Node型別結構體的指標陣列 nods[u] = p; //這裡意思就是nod[u]指向u的一個可達點(p是一箇中間指標) } void spfa(){ for(int i = 1; i <= n; i++){ //初始化 vis[i] = false; dis[i] = INF; } dis[1] = 0; vis[1] = true; Node *p; int u, v, w; queue<int>q; //佇列優化 q.push(1); //起始點是1 while(!q.empty()){ u = q.front(); q.pop(); vis[u] = false; for(p = nods[u]; p != NULL; p = p ->next){ v = p ->dot; w = p ->weight; if(dis[v] > dis[u] + w){ dis[v] = dis[u] + w; if(!vis[v]){ vis[v] = true; q.push(v); } } } } } int main(){ while(scanf("%d%d", &n, &m) != EOF){ if(n == 0 && m == 0) break; memset(nods, NULL, sizeof(nods)); //指標陣列初始化 int u, v, w; for(int i = 0; i < m; i++){ scanf("%d%d%d", &u, &v, &w); init(u, v, w); } spfa(); for(int i = 2; i <= n; i++){ //1到2,3...n的最短路 printf("%d\n", dis[i]); } } return 0; }