差分约束系统小结

  百科是这样说的:如果一个系统由n个变量和m个约束条件组成,其中每个约束条件形如xj-xi<=bk(i,j∈[1,n],k∈[1,m]),则称其为差分约束系统。亦即,差分约束系统是求解关于一组变量的特殊不等式组的方法。

  学习差分约束系统之前,必须掌握单源最短路径的算法(Bellman-ford、SPFA)。习惯上用SPFA解差分约束的题目。

  解题思想有两种:

  假设j > i,

  1、由xj - xi >=w得到xj >= xi + w,建立一条从xi->xj的边权为w的边。然后用最长路算法。

  2、由xj - xi >=w得到xi <= xj - w,建立一条从xj->xi的边权为-w的边。然后用最短路算法。

  在具体建图的时候,为了避免重复,j+1或者i-1。

  实际上,最长路和最短路算法的区别很小(SPFA模版)。

    最长路算法中dist[]初始化为负无穷,松弛的时候是if(dist[v] < dist[u] + Map[u][v]) 。

    最短路算法中dist[]初始化为正无穷,松弛的时候是if(dist[v] > dist[u] + Map[u][v]) 。

  以具体的题目作为例子吧。

  hdu1384

  题目大意是:

    给出一些区间[ai,bi]和每个区间最少需要ci个点,然后问总共最少需要几个点满足所有区间的要求。

  由于1<=ai<=bi,所以ai-1或者bi+1都是没关系的,都是可以的。(下标从0开始和1开始都行,却不能是负数)

  设s[i]是1~i 中需要的点的个数。则

  s[j+1]-s[i]>=w。这只是题目给出的数据所能建的图。

  但是有很多点是没有连通的。

  有隐含条件    0=<s[i+1] - s[i] <=1 。

  这样就可以做题了。

  如果选择建立xj >= xi + w的关系来建图,就需要用最长路经来解题。dist[]初始化为负无穷。

  具体的看代码:

  

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;

const int N = 50010, M=150010;
const int INF = 0x3f3f3f3f;
struct node
{
    int to, w, next;
};
node edge[M];
int head[N], dist[N], outq[N];
bool vis[N];
int tot;
bool SPFA(int s, int n )
{
    int i,k;
    for(i=0;i<=n;i++) dist[i]=-INF;
    memset(vis,0,sizeof(vis));
    memset(outq,0,sizeof(outq));
    queue<int > q;
    while(!q.empty()) q.pop();
    vis[s]=1;
    dist[s]=0;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=0;
        outq[u]++;
        if(outq[u]>n) return 0 ;
        k=head[u];
        while(k>=0)
        {
            if(dist[edge[k].to]-edge[k].w<dist[u])
            {
                dist[edge[k].to]=dist[u]+edge[k].w;
                if(!vis[edge[k].to])
                {
                    vis[edge[k].to]=1;
                    q.push(edge[k].to);
                }
            }
            k=edge[k].next;
        }
    }
    return 1;
}
void addedge(int i, int j ,int w)
{
    edge[tot].to=j;
    edge[tot].w=w;
    edge[tot].next=head[i];
    head[i]=tot++;
}
void init()
{
    memset(head,-1,sizeof(head));
    tot=0;
}
int main()
{
    //freopen("test.txt","r",stdin);
    int n,m,i,j,k,w,a,b;
    while(scanf("%d",&m)!=EOF)
    {
        init();
        a=INF,b=-INF;
        for(k=0;k<m;k++)
        {
            scanf("%d %d %d",&i,&j,&w);
            if(a>i) a=i;
            if(b<j+1) b=j+1;
            addedge(i,j+1,w);
        }
        for(i=a;i<=b;i++)
        {
            addedge(i,i+1,0);
            addedge(i+1,i,-1);
        }
        if(SPFA(a,b)) printf("%d\n",dist[b]);
    }
    return 0;
}

  

  

时间: 2024-10-11 21:25:56

差分约束系统小结的相关文章

差分约束系统

差分约束系统是指一系列不等式: $$ X_j - X_i \le C_{ij}(1\le i, j \le n) $$ 当然 i,j 不必取遍 1-n,而且在扩展的状况下,对于每个(i,j),可以由多个 $C_{ij}$,但是我们很容易把它们化成一个不等式. 在求解不等式组之前,我们可以分析一下这个不等式组的性质. 1. 这个不等式组是可以无解的,比如: $$X_1 - X_2 \le -1 \\ X_2 - X_3 \le -1 \\ X_3 - X_1 \le -1$$ 否则三个不等式相加得

UVa 515 - King (差分约束系统 + SPFA求带负权最短路)

下面是差分约束系统的详细介绍,以及解决方法~ 摘抄自 xuezhongfenfei(他好像也是转的....) 差分约束系统 X1 - X2 <= 0 X1 - X5 <= -1 X2 - X5 <= 1 X3 - X1 <= 5 X4 - X1 <= 4 X4 - X3 <= -1 X5 - X3 <= -3 X5 - X4 <= -3 不等式组(1) 全都是两个未知数的差小于等于某个常数(大于等于也可以,因为左右乘以-1就可以化成小于等于).这样的不等式组

差分约束系统 初见

今天初次学习差分约束系统,很神奇的东西 定义: 如果一个系统由n个变量和m个约束条件组成,其中每个约束条件形如xj-xi<=bk(i,j∈[1,n],k∈[1,m]),则称其为差分约束系统(system of difference constraints).亦即,差分约束系统是求解关于一组变量的特殊不等式组的方法. 求解差分约束系统,可以转化成图论的单源最短路径(或最长路径)问题. 其实在一些问题中需求最小值或最大值,同时需要满足一系列的不等式关系,这样就可以用到差分约束系统了,对于求最小值的问

ZOJ 3668 Launching the Spacecraft (差分约束系统,最短路)

题目: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3668 题意: 给一个初始值为0的长度为n的区间,给m个约束l,r,a,b,表示从l到r的区间和>=a且<=b,且每个数的范围为-10000~10000,问这个区间的每个数是多少,要求数尽可能大,且序列字典序最大. 方法: 差分约束系统,以前缀和表示一个节点a[i] 建图:根据下面约束条件建图 a[i]-a[i-1]<=10000 a[i-1]-a[i]&l

POJ 2983 Is the Information Reliable?(差分约束系统)

题目地址:POJ 2983 这题刚上来完全不知道跟差分约束系统有什么关系.....后来发现只要判个负环就可以.. 因为假如有冲突的话会形成一个负环.之所以建图加上一个正值一个负值,是因为这样的话,像1 2 4和1 2 3这样的数据就会形成一个负环.这个方法还是很巧妙的...然后对于V的那些不清楚的位置,就会跟P的那些等式联立形成一个不等式,然后在用最短路判环的过程中就用松弛来解决. 代码如下: #include <iostream> #include <cstdio> #inclu

【POJ 1201】 Intervals(差分约束系统)

[POJ 1201] Intervals(差分约束系统) 11 1716的升级版 把原本固定的边权改为不固定. Intervals Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23817   Accepted: 9023 Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a p

差分约束系统--详讲

------------差分约束题目请戳:差分约束题集暨报告 总的开说差分约束问题就是给出一系列不等式然后求问某一式子的最大值或者最小值. 差分约束问题具体解释: 比方有这样一组不等式: X1 - X2 <= 0 X1 - X5 <= -1 X2 - X5 <= 1 X3 - X1 <= 5                   不等式组(1) X4 - X1 <= 4 X4 - X3 <= -1 X5 - X3 <= -3 X5 - X4 <= -3 全都是

浅谈差分约束系统——图论不等式的变形

浅谈差分约束系统——图论不等式的变形 ----yangyaojia 版权声明:本篇随笔版权归作者YJSheep(www.cnblogs.com/yangyaojia)所有,转载请保留原地址! 一.定义 如若一个系统由n个变量和m个不等式组成,并且这m个不等式对应的系数矩阵中每一行有且仅有一个1和-1,其它的都为0,这样的系统称为差分约束( difference constraints )系统. 二.分析 简单来说就是给你n个变量,给m个形如x[i]-x[j]≥k①或x[i]-x[j]≤k②.求两

UVA11478 Halum [差分约束系统]

https://vjudge.net/problem/UVA-11478 给定一个有向图,每条边都有一个权值.每次你可以选择一个结点v和一个整数d,把所有以v为终点的边的权值减小d,把所有以v为起点的边的权值增加d,最后让所有边的权值的最小值大于零且尽量大. 该死书上翻译错了 >0不是非负 WA好几次因为这个 考虑每条边的约束,di表示i的halum量 w-dv+du>0 dv-du<w 但求解这个差分约束系统只是让这组不等式成立,最长路和最短路控制的都是单个d的最值而不是最小值最大 那