差分约束系统

2008-11-28 20:53:25|  分类: 算法与acm|举报|字号 订阅

 
 

出处:http://duanple.blog.163.com/blog/static/709717672008102885325526/

poj 1275 3159 1364 1716 1201 3169
这类问题,就像网络流,图论,dp,关键在列出满足的表达式,建立好数学模型,剩下的过程就很简单了。所以主要难点在于构图,从实际的描述抽象成模型。准确找到约束条件。

关于基础知识可以查看clrs 22.4节。下面只介绍我遇到的一些问题和理解。

所谓的差分约束系统,实际上指一系列的表达式,满足 形如{ xi - xj <= a}
求解实际上转化成了图论里的一个等价问题,最短路问题,实际上巧妙的利用了最短路具有的性质 di - dj <= w(j,i)
如果这样的最短路求成来了,他们的值便可以直接作为xi xj的一组可行解。

图论里求最短路,有很多方法,差分约束系统,一般利用的是单源最短路,而在单源最短路算法中,常见的是dijkstra和bellman-ford算法。这两个算法各有优劣。

dijkstra算法,效率比较高,如果用堆实现,可以达到O(vlogv+E)的复杂度,但是它只能解决正边权类型的问题,对于负边权的问题,必须采用bellman-ford算法,它的复杂度是VE.

bellman-ford算法很强大,不单可以求最短路,还可以求最长路。一般如果约束条件是 <=形式的,就标志着要求最短路,>=则要通过求最长路解决。
当然这两种约束是可以转化的,因为 xi - xj <= a实际上等价于xj- xi >= a。

一.优化途径:
1.如果改变边的松弛(relax)顺序,程序的执行顺序会有很多改观
2.当所有边都不能再松弛的时候,便可以跳出循环了,不必全部循环V-1次
这些可以通过poj1716 1201体验到
二.关于Dist[]的初始化化
1.如果将源点到各点的距离初始化为0,最终求出的最短路满足 它们之间相互最接近了
2.如果将源点到各点的距离初始化为INF(无穷大),其中之1为0,最终求出的最短路满足 它们与该点之间相互差值最大。
这些可以从poj3169 layout 得到证实。
三.
关于dikstra算法的堆实现,有两种策略,一种是一开始把全部节点放到堆里,为每个节点维护一个在堆里的索引数组。另一种策略是当当前点被更新才放到堆里,但是要注意标记已经求得最短路的哪些点,避免重复求值。
我采用的是第一种策略,去求解的poj3159 Candies

当然还有一个优化是,如果已经找到了目标点,就可以退出了,不必全部求出最短路

四.陷阱
int a[MAX] =  {INF};
注意a里面的元素只有第一个会被赋为INF,其他会被赋为0,而不是INF。

关于模型的建立,其实,很多情况下我们的 xi都是一个和式,比如从开头到现在的某个量的积累值,比如poj1716 1201中,我们要定义x[i]为点集里小于i的数的个数,则x[j] - x[i]则表示了落在线段区间[i,j]的点的个数。还有poj1364 King 也是类似,另外一些可能就是比较简单的直接的约束关系。

比较复杂的如poj1275 Cashier Employment
这个问题比较特殊,乍看其他上述问题都是寻找最小数目的点,使这些点可以覆盖线段。而这个则是找一些数目的人,而人实际上是一些线段,使这些线段可以在那些特点的总数目可以满足要求并且数目最少。关键在定义一个状态,这里如果大胆定义i时刻出纳员数目s[i],就可以了,然后利用这个s[i]便可以找到所有的约束关系,并列出不等式,这样模型就建立好了。

这个可以参考刘汝佳的书P307,图论最短路那部分,刚好以这个问题为例,而且这个问题求的就是最长路。对于sum可以二分进行优化,不过我直接穷举也过了。

poj3159 Candies
这是我接触差分约束的第一题。设S[a]为kid a获得的candies数,则每一行代表的约束是S[b]-S[a]<=c,目标函数是使得S=S[N]-S[1]最大。
利用差分约束的思想建图,对于每一条约束,从a向b做一条长为c的边,则从1到N的最短路即为所求。由于本题c皆为非负数,所以可以用Dijkstra高效解决。

转自作者:phylips@bmy的更多相关文章

  1. 转债---Pregel: A System for Large-Scale Graph Processing(译)

    转载:http://duanple.blog.163.com/blog/static/70971767201281610126277/   作者:Grzegorz Malewicz, Matthew ...

  2. LevelDB:一个快速轻量级的key-value存储库(译)

    作者:Jeff Dean, Sanjay Ghemawat 原文:http://leveldb.googlecode.com/svn/trunk/doc/index.html 译者:phylips@b ...

  3. 从LSM-Tree、COLA-Tree谈到StackOverflow、OSQA

    转自: http://blog.csdn.net/v_july_v/article/details/7526689 从LSM-Tree.COLA-Tree谈到StackOverflow.OSQA 作者 ...

  4. 分布式理论(4):Leases 一种解决分布式缓存一致性的高效容错机制(转)

    作者:Cary G.Gray and David R. Cheriton 1989 译者:phylips@bmy 2011-5-7 出处:http://duanple.blog.163.com/blo ...

  5. 浏览器内部工作原理--作者:Tali Garsiel

    本篇内容为转载,主要用于个人学习使用,作者:Tali Garsiel 一.介绍 浏览器可以被认为是使用最广泛的软件,本文将介绍浏览器的工作原理,我们将看到,从你在地址栏输入google.com到你看到 ...

  6. Eclipse自动生成作者、日期注释等功能设置

    我们在使用Eclipse 编写Java代码时,自动生成的注释信息都是按照预先设置好的格式生成的. 修改作者.日期注释格式:打开Windows->Preferences->Java-> ...

  7. SVN如何查看修改的文件记录] 来源:Linux社区 作者:frogoscar

    SVN如何查看修改的文件记录 [日期:2014-11-20] 来源:Linux社区  作者:frogoscar [字体:大 中 小]     主要是有四个命令,svn log用来展示svn 的版本作者 ...

  8. 《C++ API设计》作者Martin Reddy访谈问题征集

    Martin Reddy博士是软件行业的一名老兵,有着15年以上的从业经验,共撰写过40多篇论文,拥有3项软件专利,并与他人合著了Level of Detail for 3D Graphics.另外, ...

  9. XCode修改公司名称和作者名称

    新建的文件最上方都会有一段类似如下的版权声明 // //  ViewController.m //  CBDemoProject001 // //  Created by CB on 16/3/17. ...

随机推荐

  1. intellij idea社区版 & maven & git & tomcat/jetty 的struts2项目的搭建

    1.新建一个project,并在project下新建一个maven module.

  2. redis_笔记

    1.redis是什么 这个问题的结果影响了我们怎么用redis.如果你认为redis是一个key value store,那可能会用它来 代替mysql:如果认为它是一个可以持久化的cache,可能只 ...

  3. linux 终端快捷键

    1. 移动光标快捷键 ctrl+f 向前移动一个字符 ctrl+b 向后移动一个字符 alt+f 向前移动一个单词 alt+b 向后移动一个单词 ctrl+a 移动到当前行首 ctrl+e 移动到当前 ...

  4. Unix/Linux之命令备忘录

    ps:是显示瞬间进程的状态,并不动态连续 kill:用于杀死进程或者给进程发送信号 // 在Linux下查看所有java进程命令 ps -ef | grep java: //  停止所有java进程命 ...

  5. Apose 套打

    给web添加一个dll引用:Apose.Words 下载链接:http://yunpan.cn/cA7v6uceM6KVw  提取码 11df 在Global.asax里面的Application_S ...

  6. thymeleaf 基本语法

    四.标准表达式语法 · 简单表达式 (simple expressions) ${...}  变量表达式 *{...}  选择变量表达式 #{...}  消息表达式 @{...}  链接url表达式 ...

  7. Cassandra1.2文档学习(10)—— 插入和更新数据

    参考数据:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/dml/dml_about_ ...

  8. 虚拟内存设备驱动memdev及实例代码

    驱动: #include <linux/module.h> #include <linux/types.h> #include <linux/fs.h> #incl ...

  9. 8位灰度图在LCD上显示

    一.概述 1.灰度 灰度使用黑色调表示物体,即用黑色为基准色,不同的饱和度的黑色来显示图像.每个灰度对象都具有从 0%(白色)到灰度条100%(黑色)的亮度值. 使用黑白或灰度扫描仪生成的图像通常以灰 ...

  10. 【软件分享】文本对比工具 Beyond Compare

    转载自公众号:EmbeddDeveloper 对嵌入式感兴趣可以关注原作者博客: http://blog.csdn.net/ybhuangfugui 此处转载为分享用 Ⅰ.摘要 Beyond Comp ...