[AcWing 852] spfa判斷負環
阿新 • • 發佈:2022-05-07
點選檢視程式碼
#include<iostream> #include<cstring> #include<queue> using namespace std; const int N = 1e5 + 10; int n, m; int h[N], e[N], ne[N], w[N], idx; int dist[N], cnt[N]; bool st[N]; void add(int a, int b, int c) { e[idx] = b; w[idx] = c; ne[idx] = h[a]; h[a] = idx ++; } bool spfa() { queue<int> q; for (int i = 1; i <= n; i ++) { q.push(i); st[i] = true; } while (q.size()) { int t = q.front(); q.pop(); st[t] = false; for (int i = h[t]; i != -1; i = ne[i]) { int j = e[i]; if (dist[j] > dist[t] + w[i]) { dist[j] = dist[t] + w[i]; cnt[j] = cnt[t] + 1; if (cnt[j] >= n) return true; if (!st[j]) { q.push(j); st[j] = true; } } } } return false; } int main() { cin >> n >> m; memset(h, -1, sizeof h); while (m --) { int a, b, c; cin >> a >> b >> c; add(a, b, c); } if (spfa()) puts("Yes"); else puts("No"); return 0; }
- 開始時把所有邊都放到佇列中;(因為可能存在負環與節點 1 不連通)
- 在更新邊時,用 cnt 記錄當前路徑上面的邊的個數,一旦邊的個數大於等於 n,說明路徑上面點的個數大於等於 n + 1,而一共有 n 個點,由抽屜原理,一定有點被經過兩次,從而說明存在負環;