差分约束系统学习笔记

在这里插入图片描述

差分约束系统

差分约束系统是最短路的一类经典应用。如果一个不等式组由n个变量和m个约束条件组成,且每个约束条件都是形如 i-j≤k,1≤i≤n,1≤j≤n的不等式,则称其为 差分约束系统 (system of differenceconstraints)。差分约束系统是求解一组变量的不等式组的算法。

问题转化


我们在求解差分约束系统时,可以将其转化为图论中单源最短路(或最长路)问题。
对于不等式中的其中一组j−i≤k,我们会发现它类似最短路网络(全部由最短路上的边组成的子图)中的三角不等式d[v]−d[u]≤w<u,v>,即x[u]+w<u,v>≥x[v],所以我们可以理解成从顶点d[u]到顶点d[v]连一条权值为w<u,v>的边,用最短路算法得到最短路的答案x[i],也就求出了原不等式组的一个解。
因此我们可以将每个变量i作为一个顶点,对于约束条件x[j]-x[i]≤k,连接一条边权为k的有向边<i,j>。我们再增加一个超级源s,s连向其余每个顶点,边权均为0。如果用x[i]表示s到i的最短路, 用x[j]表示s到j的最短路,在求最短路的时候,由于边<i,j>的存在,那么一定有x[j]≤x[i]+k,自然就满足了我们的不等式了。
如果程序正常结束,那么得到的最短路答案数组d[i]就是满足条件的一组x[i]的解。
若图中存在负环,则该不等式组无解。比如存在如下一个负环

在这里插入图片描述
在这里插入图片描述
对应的不等式组为:
x[2]≤x[1]−3
x[3]≤x[2]−4
x[1]≤x[3]+4
经过替换,最终得到[1]≤x[1]−3,这是不可能成立的。所以一个负环实际上对应了一组矛盾的不等式。

在这里插入图片描述
对于下面的不等式组,我们建出的图如下。
x

两种连边方法


第一种是连边后求最短路的方法,对于x[j]−x[i]≤k,变形为x[j]≤x[i]+k,从i到j连一条权值为k的边。若加入超级源点,最后求出最短路,实际上表示在x[i]≤0 的情况下,所有x的 最大的解。若存在负环,就无解。
第二种是连边后求最长路的方法,对于x[j]−x[i]≤k,变形为x[i]≥x[j]−k,从j到i连一条权值为-k的边。若加入超级源点,最后求最长路,实际上表示在x[i]≥0 的情况下,所有x的 最小的解。若存在正环,就无解。

一道题

第一行有两个数字n,m分别表示有n个变量m个表达式。
接下来会有m行,每行有四个数字。第一个数字表示是这个表达式是大于等于,还是小于等于,或者是等于。后面的三个数字就对应上面表达式中的数字。
1:≤
2:≥
3:=

计算最小值就是计算最长路问题

直接上代码

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 1e3 + 9;
const int M = 1e4 + 9;
struct edge {
   
    int v, w, fail;
    edge() {
   }
    edge(int _v, int _w, int _fail) {
   
        v = _v;
        w = _w;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值