当前位置: 首页 > news >正文

差分约束.

差分约束

差分约束系统是一种特殊的 nnn 元一次不等式组,它包含 nnn 个变量 x1,x2,⋯ ,xnx_1,x_2,\cdots,x_nx1,x2,,xn 以及 mmm 个约束条件,每个约束条件是由其中的 两个变量做差 构成的,形如 xi−xj≤ckx_i-x_j\le c_kxixjck,其中 ckc_kck 是常数且 i≠ji\neq ji=j

我们要解决的问题就是:求一组解 x1=a1,x2=a2,⋯ ,xn=anx_1=a_1,x_2=a_2,\cdots,x_n=a_nx1=a1,x2=a2,,xn=an,使得所有约束条件得到满足,或者判断出无解。

图论建模

差分约束系统中的每个约束条件 xi−xj≤ckx_i-x_j\le c_kxixjck 都可以变成 xi≤xj+ckx_i\le x_j+c_kxixj+ck 的形式,这与单源最短路中的 三角不等式 dist[v]≤dist[u]+wdist[v]\le dist[u]+wdist[v]dist[u]+w 非常相似。

所以我们可以这样解释这个约束条件:源点到 iii 的最短距离,必然小于等于 源点到 jjj 的距离 加上 (i,j)(i,j)(i,j) 之间的 边权 ckc_kckuuuvvv单向边,边权为 www)。

显然,这样的条件在一个 具有最短路性质的图中 是必然成立的。

那么源点的选取可以简单一些,如我们令 000超级源点,且向所有结点连接一条边权为 000 的单向边。

此时整个图连通,而具有最短路性质的图只需要判断图中是否有负环即可。

又因为 dijkstradijkstradijkstra 只能用于处理非负权边的图,所以我们考虑用 Bellman−FordBellman-FordBellmanFord 算法。

简单介绍一下 Bellman−FordBellman-FordBellmanFord 算法。

首先令源点 sss 的最短路 dist[s]=0dist[s]=0dist[s]=0,其他的都是无穷大。

然后遍历所有的边 (u,v)(u,v)(u,v),如果 dist[u]dist[u]dist[u] 不是无穷大,并且满足 dist[v]>dist[u]+wdist[v]>dist[u]+wdist[v]>dist[u]+w,那么就代表能松弛。

我们遍历所有的边 n−1n-1n1 轮,因为 边的遍历顺序问题,所有的点最多需要 n−1n-1n1 轮才能松弛完。

边的遍历顺序问题指的是,整个图是一条链,且与源点有关的边被放在最后一条,以此类推。

所以一轮遍历只松弛了一个点,至多需要 n−1n-1n1 轮遍历 才能松弛所有点。

检查负环 的方法就是,当遍历了 n−1n-1n1 轮后,再遍历一轮,如果还能进行松弛,说明必然有负环。

#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize(2)
#define int long long
#define endl '\n'
#define PII pair<int,int>
#define INF 1e18
const int N = 1e4;int dist[N], vis[N];
vector<PII> g[N];bool BellmanFord(int s, int n) {dist[s] = 0;bool flag = 0;for (int i = 1; i <= n; i++) {flag = 0;for (int u = 1; u <= n; u++) {for (auto [v, w] : g[u]) {if (dist[u] != INF && dist[v] > dist[u] + w) {dist[v] = dist[u] + w;flag = 1;}}}if (!flag) break;}return flag; // 如果 flag = 1,说明有负环,否则没有负环
}void slove () {int n, m;cin >> n >> m;while (m--) {int op, u, v, w;cin >> op;if (op == 1) {cin >> u >> v >> w;// dist[u] >= dist[v] + w// dist[v] <= dist[u] - wg[u].emplace_back(v, -w);} else if (op == 2) {cin >> u >> v >> w;// dist[u] - dist[v] <= w// dist[u] <= dist[v] + wg[v].emplace_back(u, w);} else {cin >> u >> v;g[u].emplace_back(v, 0);g[v].emplace_back(u, 0);}}for (int i = 1; i <= n; i++) {g[0].emplace_back(i, 0);}bool is_ok = BellmanFord(0, n);if (is_ok) cout << "No" << endl;else cout << "Yes" << endl;
}signed main () {ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);slove();
}
http://www.dtcms.com/a/335034.html

相关文章:

  • 腾讯混元大模型:实现3D打印产品生成的自动化平台
  • [Python 基础课程]继承
  • [Linux] RAID存储技术
  • 【102页PPT】电子行业数字化解决方案(附下载方式)
  • 容器化部署:用Docker封装机器翻译模型与服务详解
  • 服务器可以ping通,但部署的网站打不开
  • MyBatis 的 SQL 拦截器:原理、实现与实践
  • 基于Spring Boot的快递物流仓库管理系统 商品库存管理系统
  • OpenStack Neutron中的L2 Agent与L3 Agent:新手友好指南
  • Nginx蜘蛛请求智能分流:精准识别爬虫并转发SEO渲染服务
  • RemoteCtrl-初步的网络编程框架搭建
  • Linux 多线程:线程回收策略 线程间通信(互斥锁详解)
  • Easytier异地组网与Nginx反向代理
  • 昇腾AI自学Day2-- 深度学习基础工具与数学
  • 楼宇自控系统赋能建筑全维度管理,实现环境、安全与能耗全面监管
  • 计算分组内时间列的最大差值
  • 【AI论文】NextStep-1:迈向大规模连续令牌自回归图像生成
  • Warning: Unable to create personal MATLAB work folder:E:\绯荤粺榛樿\鏂囨。\MATLAB
  • 1083. 数列极差问题
  • 【深度学习】基于ESRNet模型的图像超分辨率训练
  • pytest介绍(python测试框架)(@pytest.mark.parametrize、@pytest.fixtures)
  • ClaudeCode使用指南
  • 鲁老师深度学习笔记(1)—最大似然估计
  • Flutter Provider 模式实现:基于 InheritedWidget 的状态管理实现
  • 93、23种设计模式之抽象工厂模式
  • 【读论文】医疗AI大模型:百川开源Baichuan-M2
  • 23. CommonJS 和 ES6 Module 区别
  • 19.3 Transformers量化模型极速加载指南:4倍推理加速+75%显存节省实战
  • ArrayList的contains问题
  • 【C++学习篇】:基础