POJ 3259 判斷圖中是否存在負權迴路
阿新 • • 發佈:2019-02-18
#include<iostream> #include<fstream> using namespace std; struct Edge { int s; int e; int t; }; static const int MAX = 30000; static const int MAXEDGES = 6000; /* caution */ static const int MAXNODES = 501; static int n, m, w; struct Edge edges[MAXEDGES]; static int dist[MAXNODES]; //#define DEBUG int bellman_ford(void) { int edgenum = m + m + w; /* edges */ int i, j; for (i = 1; i <= n; i++) { dist[i] = MAX; } dist[1] = 0; for (i = 1; i < n; i++) /* Relax all edges |v|-1 times */ { int ok = 1; /* reduce about 80ms */ for (j = 0; j < edgenum; j++) { int s, e, t; s = edges[j].s; e = edges[j].e; t = edges[j].t; if (dist[s] + t < dist[e]) { dist[e] = dist[s] + t; ok = 0; } } if (ok) break; } for (j = 0; j < edgenum; j++) /* check minus loop */ { int s, e, t; s = edges[j].s; e = edges[j].e; t = edges[j].t; if (dist[s] + t < dist[e]) return 0; } return 1; } int main() { #ifdef DEBUG fstream cin("G:\\book\\algorithms\\acm\\Debug\\dat.txt"); #endif int fields; cin >> fields; while (fields-- >0) { cin >> n >> m >> w; int i, k = 0; int s, e, t; for (i = 0; i < m; i++) { cin >> s >> e >>t; edges[k].s = s; edges[k].e = e; edges[k++].t = t; edges[k].s = e; edges[k].e = s; edges[k++].t = t; } for (i = 0; i < w; i++) { cin >> s >> e >>t; edges[k].s = s; edges[k].e = e; edges[k++].t = -t; /* minus weigh edge */ } if (!bellman_ford()) cout << "YES" << endl; else cout << "NO" << endl; } return 0; }
演算法的正確性見 演算法導論 24.1節相關內容。
存在負權迴路,負權迴路上的頂點可以進行無限制的鬆弛。
存在負權路徑無法進行最短路徑的計算見 演算法導論 圖24 -1即可明白。
程式碼中加註釋的地方,都曾經出現過錯誤,注意。