差分约束
差分约束系统 是一种特殊的
差分约束系统中的每个约束条件
注意到,如果
设
一般使用 Bellman-Ford 或队列优化的 Bellman-Ford(俗称 SPFA,在某些随机图跑得很快)判断图中是否存在负环,最坏时间复杂度为
常用变形技巧¶
例题luogu P1993 小 K 的农场¶
题目大意:求解差分约束系统,有
题意 | 转化 | 连边 |
---|---|---|
add(a, b, -c); | ||
add(b, a, c); | ||
add(b, a, 0), add(a, b, 0); |
跑判断负环,如果不存在负环,输出 Yes
,否则输出 No
。
给出一种用 DFS-SPFA 实现的判负环(时间复杂度极度不稳定):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #include <algorithm> #include <cstdio> #include <cstring> using namespace std; const int maxn = 400010; int n, m, op, u, v, we, cur, h[maxn], nxt[maxn], p[maxn], w[maxn], dist[maxn]; bool tf[maxn], ans; inline void add_edge(int x, int y, int z) { cur++; nxt[cur] = h[x]; h[x] = cur; p[cur] = y; w[cur] = z; } void dfs(int x) { tf[x] = true; for (int j = h[x]; j != -1; j = nxt[j]) if (dist[p[j]] > dist[x] + w[j]) { if (tf[p[j]] || ans) { ans = 1; break; } dist[p[j]] = dist[x] + w[j]; dfs(p[j]); } tf[x] = false; } int main() { cur = 0; ans = false; memset(h, -1, sizeof h); memset(dist, 127, sizeof dist); scanf("%d%d", &n, &m); while (m--) { scanf("%d%d%d", &op, &u, &v); if (op == 1) scanf("%d", &we), add_edge(u, v, -we); else if (op == 2) scanf("%d", &we), add_edge(v, u, we); else if (op == 3) add_edge(u, v, 0), add_edge(v, u, 0); } for (int i = 1; i <= n; i++) { dfs(i); if (ans) break; } if (ans) printf("No\n"); else printf("Yes\n"); return 0; } |
例题P4926[1007]倍杀测量者¶
不考虑二分等其他的东西,这里只论述差分系统
对每个
Bellman-Ford 判负环代码实现¶
下面是用 Bellman-Ford 算法判断图中是否存在负环的代码实现,请在调用前先保证图是连通的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | bool Bellman_Ford() { for (int i = 0; i < n; i++) { bool jud = false; for (int j = 1; j <= n; j++) for (int k = h[j]; ~k; k = nxt[k]) if (dist[j] > dist[p[k]] + w[k]) dist[j] = dist[p[k]] + w[k], jud = true; if (!jud) break; } for (int i = 1; i <= n; i++) for (int j = h[i]; ~j; j = nxt[j]) if (dist[i] > dist[p[j]] + w[j]) return false; return true; } |
习题¶
bzoj 1715:[Usaco2006 Dec]Wormholes 虫洞
POJ 2983 Is the Information Reliable?
build本页面最近更新:,更新历史
edit发现错误?想一起完善? 在 GitHub 上编辑此页!
people本页面贡献者:
copyright本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用