“能够”没有环,最多\(|V|-1\)条边html
有负环则不存在最短路ios
会造成最短路径树算法
最大化 \(d_i\)优化
知足spa
说明:上述约束对应了无穷组解。最短路求的是知足约束的最大值。由于三角不等式要求取等号时w(u,v)是最短路上的边。code
差分约束系统htm
通常使用spfa或者缩点后dpblog
应为dijkstra有贪心策略的限制队列
将全部点入队,且\(d_i=0\)ci
负环只看不等约束,不看初始值
01分数规划
见最后
和最短路的线性规划形式相似的一类线性规划问题
也是须要初值的,对应d[s]=0
最大化
有负环则无解
图不连通 无关 任意解
最小化
有正环则无解
图不连通 无关 任意解
固然也能够转化成最短路
判负环的代码
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int N = 2005, M = 3005; inline int read() { int x = 0, f = 1; char c = getchar(); while(c<'0' || c>'9') {if(c=='-') f=-1; c=getchar();} while(c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();} return x * f; } int n, m; struct edge {int v, ne, w, u;} e[M<<1]; int cnt, h[N]; inline void ins(int u, int v, int w) { e[++cnt] = (edge) {v, h[u], w, u}; h[u] = cnt; } int d[N], cou[N]; bool bellman_ford() { for(int i=1; i<=n; i++) d[i] = cou[i] = 0; for(int i=1; i<=n; i++) { for(int i=1; i<=cnt; i++) { int u = e[i].u, v = e[i].v; //printf("hi %d %d %d %d\n", u, v, d[u], d[v]); if(d[v] > d[u] + e[i].w) { d[v] = d[u] + e[i].w; cou[v] = cou[u] + 1; if(cou[v] >= n) return false; if(i == n) return false; } } } return true; } int main() { freopen("in", "r", stdin); int T = read(); while(T--) { cnt = 0; memset(h, 0, sizeof(h)); n = read(); m = read(); for(int i=1; i<=m; i++) { int u = read(), v = read(), w = read(); if(w < 0) ins(u, v, w); else ins(u, v, w), ins(v, u, w); } puts(bellman_ford() ? "N0" : "YE5"); } }
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int N = 2005, M = 3005; inline int read() { int x = 0, f = 1; char c = getchar(); while(c<'0' || c>'9') {if(c=='-') f=-1; c=getchar();} while(c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();} return x * f; } int n, m; struct edge {int v, ne, w;} e[M<<1]; int cnt, h[N]; inline void ins(int u, int v, int w) { e[++cnt] = (edge) {v, h[u], w}; h[u] = cnt; } int d[N], cou[N], inq[N], cinq[N]; int q[N], head, tail; inline void lop(int &x) {if(x==N) x=1;} bool spfa() { head = tail = 1; for(int i=1; i<=n; i++) d[i] = cou[i] = 0, inq[i] = cinq[i] = 1, q[tail++] = i; while(head != tail) { int u = q[head++]; lop(head); inq[u] = 0; for(int i=h[u]; i; i=e[i].ne) { int v = e[i].v; if(d[v] > d[u] + e[i].w) { d[v] = d[u] + e[i].w; cou[v] = cou[u] + 1; if(cou[v] >= n) return false; if(!inq[v]) { q[tail++] = v; lop(tail); inq[v] = 1; if(++cinq[v] >= n) return false; } } } } return true; } int main() { freopen("in", "r", stdin); int T = read(); while(T--) { cnt = 0; memset(h, 0, sizeof(h)); n = read(); m = read(); for(int i=1; i<=m; i++) { int u = read(), v = read(), w = read(); if(w < 0) ins(u, v, w); else ins(u, v, w), ins(v, u, w); } puts(spfa() ? "N0" : "YE5"); } }