P5960 【模板】差分约束算法

差分约束系统
给出 n 个变量和 m 个约束条件,形如 xi−xj≤ckx_i - x_j \leq c_kxi​−xj​≤ck​,你需要求出一组解,使得所有约束条件均被满足。
怎样解这个差分约束系统呢?我们将上面的不等式变形一下:xi≤xj+ckx_i \leq x_j + c_kxi​≤xj​+ck​
容易发现这个形式和最短路中的三角形不等式 disv≤disu+wdis_v \leq dis_u + wdisv​≤disu​+w非常相似。
因此我们就将这个问题转化为一个求最短路的问题:比如对于上面这个不等式,我们从 j 向 i 连一条权值为 ckc_kck​的边。接下来,我们再新建一个 0 号点,从 0 号点向其他所有点连一条权值为 0 的边。这个操作相当于新增了一个变量 x0x_0x0​和 n 个约束条件:xi≤x0x_i \leq x_0xi​≤x0​,从而将所有变量都和 x0x_0x0​这一个变量联系起来。
然后以 0 号点为起点,用 spfa 跑最短路。如果有负权环,差分约束系统无解。否则设从 0 号点到 i 号点的最短路为 disidis_idisi​,则 xi=disix_i = dis_ixi​=disi​即为差分约束系统的一组可行解

如上图,该图存在负环,如果一直沿着负环走,最短路径将会越来越小,最后到达−∞-∞−∞。
而此时的不等式就会出现矛盾,也就以为着没有正确的解

常用技巧

很多时候差分约束的条件并不是简单的小于等于号,这时候我们需要稍微做点变形。

  • 如果有 xi−xj≥ckx_i - x_j \geq c_kxi​−xj​≥ck​,则可以两边同时乘 −1,将不等号反转过来。

  • 如果有 xi−xj=ckx_i - x_j = c_kxi​−xj​=ck​,则可以把这个等式拆分为 xi−xj≤ckx_i - x_j \leq c_kxi​−xj​≤ck​和 xi−xj≥ckx_i - x_j \geq c_kxi​−xj​≥ck​两个约束条件,如果要求的是最值问题,那么我们应该统一符号,A=BA = BA=B改成A>=B,B>=AA>= B,B>= AA>=B,B>=A。

#include<map>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
#include<vector>using namespace std;const int N = 5007;
const int M = 50007;
const int INF = 0x3f3f3f3f;
typedef pair<int,int> PII;int n,m;
int ver[M],edge[M],nex[M],head[N],tot;
int dis[N],vis[N],cnt[N];void add(int x,int y,int z){ver[++tot] = y;edge[tot] = z;nex[tot] = head[x];head[x] = tot;
}bool spfa(int s){queue<int>q;memset(vis,0,sizeof vis);memset(dis,0x3f,sizeof dis);dis[s] = 0;vis[s] = 1;q.push(s);while(q.size()){int x = q.front();q.pop();vis[x] = 0;for(int i = head[x];i;i = nex[i]){int y = ver[i],z = edge[i];if(dis[y] > dis[x] + z){dis[y] = dis[x] + z;cnt[y] = cnt[x] + 1;if(cnt[y] >= n)return false;if(!vis[y]){vis[y] = 1;q.push(y);}}}}return true;
}int main(){scanf("%d%d",&n,&m);for(int i = 1;i <= n;++i)//建超级源点add(0,i,0);for(int i = 1;i <= m;++i){int x,y,z;scanf("%d%d%d",&x,&y,&z);add(y,x,z);//xi - xj ≤ k//j来更新i,所以j向i连一条权值为k的边}if(!spfa(0))puts("NO");else {for(int i = 1;i <= n;++i)printf("%d ",dis[i]);puts("");}return 0;
}

解题报告:P5960 【模板】差分约束算法(及常用技巧)相关推荐

  1. 【模板】差分约束算法

    [模板]差分约束算法 题意: 题解: 模板题 算法讲解 给出一组包含 m 个不等式,有 n 个未知数.求任意一组满足这个不等式组的解,或判定无解. 连边之后跑最短路,保证每个连通块都没有负环即可. 也 ...

  2. 【图论】差分约束算法详解

    一.前言 在介绍差分约束之前,我们首先需要知道差分约束是用来解决什么问题的:差分约束是一个用来解决形如 X<=Y+c 的二元不等式组的可行解的一个算法.在高中数学中我们会学习如何使用线性规划的方 ...

  3. 洛谷OJ:P5960 【模板】差分约束算法

    思路:差分约束模板题,注意使用SPFA来判断负环,也即无解的情况. #include<queue> #include<vector> #include<string> ...

  4. ACM模板——差分约束

    a-b≤c a到b连一条c 最短路判负环,有负环就不行 转载于:https://www.cnblogs.com/Asurudo/p/11533296.html

  5. 算法题常用技巧C++

    刷题常用技巧C++ 常用头文件 #include <iostream> #include <cstdio> #include <fstream> #include ...

  6. 【POJ - 1275】Cashier Employment(差分约束,建图)

    题干: A supermarket in Tehran is open 24 hours a day every day and needs a number of cashiers to fit i ...

  7. 【HDU - 3440】House Man(差分约束)

    题干: In Fuzhou, there is a crazy super man. He can't fly, but he could jump from housetop to housetop ...

  8. 2021字节跳动校招秋招算法面试真题解题报告--leetcode148 排序链表,内含7种语言答案

    148.排序链表 1.题目描述 在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序 2.解题报告 针对nlogn的排序算法,主要有快速排序,归并排序和堆排序.其中,堆排序利用了数 ...

  9. poj1716(差分约束+SPFA)

    题意:整数间隔[a,b],a<b,是以a开头和以b结尾的所有连续整数的集合.在包含至少两个不同整数的集合中找到每个间隔的最小元素数. 思路:采用差分约束算法:当问题可以转化为形如一组 xi‑x' ...

最新文章

  1. OUYA游戏开发快速入门教程第1章了解OUYA及其设备
  2. 云原生生态周报 Vol. 17 | Helm 3 发布首个 beta 版本
  3. php怎么上传函数,php上传函数怎么封装
  4. 多线程编程学习笔记——线程池(二)
  5. Linux的最大文件限制数ulimit
  6. Newton迭代法求无约束目标函数极小值matlab实现
  7. 【洛谷 P2764】 最小路径覆盖问题(最大流)
  8. c语言指针知识点小结,C语言指针知识点总结
  9. 《自己动手写网络爬虫》笔记2-Http状态码
  10. STM32MP157 Linux系统移植开发篇16:Linux内核音频驱动移植
  11. 电脑自带的edge浏览器无法访问解决问题
  12. 【LoRaWan】节点端(一)--SX1278介绍
  13. centos7图形界面和dos界面
  14. xml组合时间串解析
  15. 笔记本电脑C盘变红或变满,怎么处理?
  16. 抖音SEO优化源码,企业号搜索排名系统,矩阵分发。
  17. 深圳Java学习:Java中的原子操作
  18. HTML下拉框选择事件
  19. 《深入理解Windows操作系统》笔记4
  20. 什么时间段申购新股?新股申购的八大时机!确定时机能挽回三年损失!

热门文章

  1. 酷炫的深度学习网络图怎么绘制出来的?
  2. 工业机器人抓取时怎么定位的?用什么传感器来检测?
  3. 2012年至今,细数深度学习领域这些年取得的经典成果
  4. FBI很气愤:黑了CIA的熊孩子又回来了
  5. golang的包管理系统比较
  6. NS_ASSUME_NONNULL_BEGIN 延伸
  7. 2012-4-2 通过MdiParent设置窗体最前
  8. app开发外包的流程、需求、报价,需要知道的细节!
  9. 大学毕业了,你是否需要需要职业化培训!
  10. Html5 Canvas 扫雷 (IE9测试通过)