【spfa】AcWing852.spfa判斷負環
阿新 • • 發佈:2022-05-29
AcWing852.spfa判斷負環
題解
判斷負環的思路:利用抽屜原理,當邊數為n時,若要連成一條無環的直線我們需要n+1個點,但我們只有n個點,故可以判斷出存在環。
且由於spfa更新路徑的特性,代表這個環會使得路徑變小,即這個環為負權環
#include <iostream> #include <queue> #include <cstring> using namespace std; const int N = 2010, M = 10010; bool st[N]; int dist[N], cnt[N]; int n, m; int h[N], e[M], ne[M], w[M], idx; void add(int a, int b, int c) { ne[idx] = h[a], h[a] = idx, e[idx] = b, w[idx++] = c; } 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; 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() { memset(h, -1, sizeof h); cin >> n >> m; int a, b, c; for(int i = 0; i < m; ++i) { cin >> a >> b >> c; add(a, b, c); } if(spfa()) cout << "Yes" << endl; else cout << "No" << endl; return 0; }