<学习笔记> 查分约束系统

定义:如果一个系统由n个变量和m个约束条件组成,形成m个形如 ai - aj ≤ k 的不等式(i,j∈[1,n],k为常数),则称其为差分约束系统(system of difference constraints)。亦即,差分约束系统是求解关于一组变量的特殊不等式组的方法。

栗子:给出这样的一组不等式

A-B < = 3

B-C < = 6

C-D < = 5

E-C < = 2

B-E < = 3

求A-D的最大值。

经过一番脑跑之后,得出答案13。但是我们不能总是脑跑啊。。。费脑子QAQ,所以有什么科学的求法吗??

我们对A-B < = 3进行移项,改为 A < = B + 3 ,发现类似于最短路中的不等式 de[t] < =  de[f] + d ,可以看做是从B到A连了一条权值为3的边。我们把上面的不等式画成图。

发现答案即为D到A的最短路。

为什么呢??

把图单个剥离出来看

已知 (1) B-A < = x ;(2) C - B < = Y ;(3) C - A < = z .

则 C-A 的最大值 即为 1+2 和 3 比较 ,也就是 C-A<=x+y 与 C-A <=z 答案即为 min(x+y,z) (小小取更小),即为从A到C的最短路。

字面理解为B比A最大大x,C比B最大大y,C就比A最大大x+y,C又比A最大大z,所以我们要求一个x+y和z的最小值。

把它扩展为n个点,m条边的图,每一条边都是一个可传递的大小关系。S到T的路径可以看做许多S与T之间的大小关系(T-S < = ... ),我们要求的T-S的最大值就是最小的限制,也就是A到C最短路。

同理 B-A > = x , C-B > = y , C-A > = z ,也可以抽象为 de[t] > = de[f] + d ,这就转变为了最长路问题 ,这是求 C-A 的最小值 , 与上面思想相同。

也就是最大求最短,最小求最长。

关于Dist[]的初始化

1.如果将源点到各点的距离初始化为0,最终求出的最短路满足它们之间相互最接近了

2.如果将源点到各点的距离初始化为INF(无穷大),其中之1为0,最终求出的最短路满足 它们与该点之间相互差值最大。(from  baidubaike)

但是题目里给出的不等式不一定大于小于号的方向相同,如 求最大值时却给出了 D-E > = q , 只需要转化成 E-D < = -q 就可以了。(D到E连了一条边权为-q的边)。

那么问题又来了,不等式一定有解吗??

不一定。

数学上,多个不等式的解集分为 空集 , 有限集,无限集(暂且这么叫qwq)。

发现,若是S无法到T,即为无限多解(没有限制)。若S到T的路径上有环(最短路的负环,最长路的正环),无法取到最大值或最小值。

emmm。。。百度百科上的有关知识

引理:设x=(x1,x2,…,xn)是差分约束系统Ax≤b的一个解,d为任意常数。则x+d=(x1+d,x2+d,…,xn+d)也是该系统Ax≤b的一个解。

定理:将如上差分约束系统转换成图后,以为源点得到的最短路径序列为(如果有解),则满足且若任意解,则有

查查分约束时查到的神犇博客,十分详细易理解%%%

栗子 : codevs 2404 糖果

代码 qwq

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<deque>
 7 using namespace std;
 8
 9 int N,K,X,A,B,cnt,f;
10 int first[100010],next[400010],rd[100010];
11 long long de[100010],ans;
12 bool used[100010];
13
14 struct maple{
15    int f,t,d;
16 }Rode[400010];
17 deque<int> q;
18
19 void Build(int f,int t,int d)
20 {
21     Rode[++cnt]=(maple){f,t,d};
22     next[cnt]=first[f];
23     first[f]=cnt;
24 }
25 void SPFA() // 跑最长路
26 {
27     used[0]=1;
28     de[0]=1;  // 保证每个人都分到糖果
29     q.push_back(0);
30     while(!q.empty())
31     {
32         int a=q.front();
33         q.pop_front();
34         used[a]=0;
35         for(int i=first[a];i;i=next[i])
36            if(de[Rode[i].t]<de[a]+Rode[i].d)
37            {
38                   de[Rode[i].t]=de[a]+Rode[i].d;
39                   if(!used[Rode[i].t])
40                   {
41                          used[Rode[i].t]=1;
42                          if(!q.empty()&&de[Rode[i].t]>=de[q.front()]) q.push_front(Rode[i].t);
43                          else q.push_back(Rode[i].t);
44                          ++rd[Rode[i].t];
45                          if(rd[Rode[i].t]>=N)  // 判断是否有解
46                          {
47                                 f=1;
48                                 break;
49                          }
50                   }
51            }
52         if(f) break;
53     }
54 }
55 int main()
56 {
57     scanf("%d%d",&N,&K);
58     for(int i=1;i<=K;++i)
59     {
60         scanf("%d%d%d",&X,&A,&B);
61         if(X==1) Build(A,B,0),Build(B,A,0); // A = B
62         if(X==2) Build(A,B,1);   // B - A > = 1
63         if(X==3) Build(B,A,0);   // A - B > = 0
64         if(X==4) Build(B,A,1);   // A - B > = 1
65         if(X==5) Build(A,B,0);   // B - A > = 0
66     }
67     for(int i=1;i<=N;++i) Build(0,i,0); // i - 0 > = 0
68     SPFA();
69     if(f) cout<<-1;
70     else{
71         for(int i=1;i<=N;++i)
72            ans+=de[i];
73         printf("%lld",ans);
74     }
75     return 0;
76 }

(部分内容参考自各神犇博客,侵删 qwq)

时间: 2024-11-05 22:55:14

<学习笔记> 查分约束系统的相关文章

POJ1201 Intervals查分约束系统(最短路)

Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: reads the number of intervals, their end points and integers c1, ..., cn from the standard input, computes the minimal size of a set Z of

BZOJ 3436 小K的农场 查分约束系统 SPFA判负环

题目大意:农场中有一些土地,上面会长一些作物,现在给出一些约束条件,问有没有这种可能. 思路:裸的查分约束系统判负环.记住要跑最长路. CODE: #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 100010 using namespace std; int points,asks;

算法学习笔记系列——分治法

一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换). 二.基本思想及策略 分治法设计思想:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之. 分治策略是:对于一个规模为n的问题,若该

HDU 1384 查分约束

点击打开链接 题意:给了n个区间,要求每个区间至少有C个数字出现,问满足的最小的数字个数 思路:用Si代表0到i的区间内的数字个数,然后可以写出查分约束方程,对于一个区间则Sa-S(b-1)>=C的,然后隐含的一个条件就是Si-S(i-1)>=0且<=1的,然后泡个最长路就行,对于查分约束系统求最大值是<=的形式,而求最小值则是>=的形式 #include <queue> #include <stdio.h> #include <stdlib.h

Eclipse插件开发 学习笔记 PDF 第一篇到第四篇 免分下载 开发基础 核心技术 高级进阶 综合实例

<<Eclipse插件开发 学习笔记>>,本书由浅入深.有重点.有针对性地介绍了Eclipse插件开发技术,全书分为4篇共24章.第一篇介绍Eclipse平台界面开发的基础知识.包含SWT控件的使用.界面布局.事件处理等内容:第二篇是插件开发核心技术,主要介绍插件开发的核心知识要点,包含行为(Action).视图(ViewPart).编辑器(Editor).透视图(Perspective)等10章的内容.第三篇主要讲述插件开发的高级内容,包含开发高级内容.富client平台技术(R

Mysql学习笔记(三)对表数据的增删改查。

写在前面:(一些牢骚,可以直接跳到分割线后) 太过敏感的人不会快乐,不幸的是我正是这种性格的人. 从培训机构毕业后,迫于经济方面的压力,和当时的班里的一个同学住在了一起,我们在一个公司上班.谁知道这都是不开心生活的源头,从每天早晨开始心情就很糟糕.他是个脾气很慢的人,我是个急脾气,特别是在早上上班的时候.由此种种吧,实在是不胜枚举.算了,还是不说了,太痛苦了,我不太喜欢说别人的坏话.我是学心理学的,已经用各种方法去安慰自己,但是都不太奏效. 回想以往和朋友的交往中,我虽然不算十分合群的人,但绝对

MySQL数据库学习笔记(十二)----开源工具DbUtils的使用(数据库的增删改查)

[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4085684.html 联系方式:[email protected] [正文] 这一周状态不太好,连续打了几天的点滴,所以博客中断了一个星期,现在继续. 我们在之前的几篇文章中学习了JDBC对数据库的增删改查.其实在实际开发中,一般都是使用第三方工具类,但是只有将之前的基础学习好了,在使用开源工具的

Mysql学习笔记(六)增删改查

原文:Mysql学习笔记(六)增删改查 PS:数据库最基本的操作就是增删改查了... 学习内容: 数据库的增删改查 1.增...其实就是向数据库中插入数据.. 插入语句 insert into table_name values("要插入的数据"); 比如说,我们先创建一个宠物表,用来记录宠物的基本信息以及所有者... create table pet ( name varchar(20), owner varchar(20), species varchar(20), sex cha

EF6 学习笔记(二):操练 CRUD 增删改查

接上篇: http://www.cnblogs.com/jacky-zhang/p/7373607.html 原文链接: https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-basic-crud-functionality-with-the-entity-framework-in-asp-net-mvc-applica