人人范文网 范文大全

差分约束

发布时间:2020-03-02 21:50:26 来源:范文大全 收藏本文 下载本文 手机版

(本文假设读者已经有以下知识:最短路径的基本性质、Bellman-Ford算法。)

比如有这样一组不等式:

X1X5

不等式组(1)

全都是两个未知数的差小于等于某个常数(大于等于也可以,因为左右乘以-1就可以化成小于等于)。这样的不等式组就称作差分约束系统。

这个不等式组要么无解,要么就有无数组解。因为如果有一组解{X1, X2, ..., Xn}的话,那么对于任何一个常数k,{X1 + k, X2 + k, ..., Xn + k}肯定也是一组解,因为任何两个数同时加一个数之后,它们的差是不变的,那么这个差分约束系统中的所有不等式都不会被破坏。

差分约束系统的解法利用到了单源最短路径问题中的三角形不等式。即对于任何一条边u -> v,都有:

d(v)

其中d(u)和d(v)是从源点分别到点u和点v的最短路径的权值,w(u, v)是边u -> v的权值。

显然以上不等式就是d(v)Xj Vi,权值为c。最后,我们在这张图上求一次单源最短路径,这些三角形不等式就会全部都满足了,因为它是最短路径问题的基本性质嘛。

话说回来,所谓单源最短路径,当然要有一个源点,然后再求这个源点到其他所有点的最短路径。那么源点在哪呢?我们不妨自已造一个。以上面的不等式组为例,我们就再新加一个未知数X0。然后对原来的每个未知数都对X0随便加一个不等式(这个不等式当然也要和其它不等式形式相同,即两个未知数的差小于等于某个常数)。我们索性就全都写成XnX0

不等式组(2)

对于这5个不等式,也在图中建出相应的边。最后形成的图如下:

图1 图中的每一条边都代表差分约束系统中的一个不等式。现在以V0为源点,求单源最短路径。最终得到的V0到Vn的最短路径长度就是Xn的一个解啦。从图1中可以看到,这组解是{-5, -3, 0, -1, -4}。当然把每个数都加上10也是一组解:{5, 7, 10, 9, 6}。但是这组解只满足不等式组(1),也就是原先的差分约束系统;而不满足不等式组(2),也就是我们后来加上去的那些不等式。当然这是无关紧要的,因为X0本来就是个局外人,是我们后来加上去的,满不满足与X0有关的不等式我们并不在乎。

也有可能出现无解的情况,也就是从源点到某一个顶点不存在最短路径。也说是图中存在负权的圈。这一点我就不展开了,请自已参看最短路径问题的一些基本定理。

其实,对于图1来说,它代表的一组解其实是{0, -5, -3, 0, -1, -4},也就是说X0的值也在这组解当中。但是X0的值是无可争议的,既然是以它作为源点求的最短路径,那么源点到它的最短路径长度当然是0了。因此,实际上我们解的这个差分约束系统无形中又存在一个条件:

X0 = 0

也就是说在不等式组(1)、(2)组成的差分约束系统的前提下,再把其中的一个未知数的值定死。这样的情况在实际问题中是很常见的。比如一个问题表面上给出了一些不等式,但还隐藏着一些不等式,比如所有未知数都大于等于0或者都不能超过某个上限之类的。比如上面的不等式组(2)就规定了所有未知数都小于等于0。 对于这种有一个未知数定死的差分约束系统,还有一个有趣的性质,那就是通过最短路径算法求出来的一组解当中,所有未知数都达到最大值。下面我来粗略地证明一下,这个证明过程要结合Bellman-Ford算法的过程来说明。

假设X0是定死的;X1到Xn在满足所有约束的情况下可以取到的最大值分别为M

1、M

2、„„、Mn(当然我们不知道它们的值是多少);解出的源点到每个点的最短路径长度为D

1、D

2、„„、Dn。

基本的Bellman-Ford算法是一开始初始化D1到Dn都是无穷大。然后检查所有的边对应的三角形不等式,一但发现有不满足三角形不等式的情况,则更新对应的D值。最后求出来的D1到Dn就是源点到每个点的最短路径长度。

如果我们一开始初始化D

1、D

2、„„、Dn的值分别为M

1、M

2、„„、Mn,则由于它们全都满足三角形不等式(我们刚才已经假设M1到Mn是一组合法的解),则Bellman-Ford算法不会再更新任合D值,则最后得出的解就是M

1、M

2、„„、Mn。

好了,现在知道了,初始值无穷大时,算出来的是D

1、D

2、„„、Dn;初始值比较小的时候算出来的则是M

1、M

2、„„、Mn。大家用的是同样的算法,同样的计算过程,总不可能初始值大的算出来的结果反而小吧。所以D

1、D

2、„„、Dn就是M

1、M

2、„„、Mn。

那么如果在一个未知数定死的情况下,要求其它所有未知数的最小值怎么办?只要反过来求最长路径就可以了。最长路径中的三角不等式与最短路径中相反:

d(v) >= d(u) + w(u, v) 也就是 d(v) - d(u) >= w(u, v)

所以建图的时候要先把所有不等式化成大于等于号的。其它各种过程,包括证明为什么解出的是最小值的证法,都完全类似。

用到差分约束系统的题目有ZJU 2770,祝好运。

标签: acm zju 最短路径 差分约束 bellman-ford difference constraint

相关文章:

LCA-RMQ和TreeDP:PKU 3417 今天做了若干题,不过Pku 3417是我记忆最深的一道题。

自恋地给一个通过数据:

16 3556389 EZ_dla 21060K 516MS Pascal 3397B 2008-06-29 00:53:44

首先概括题意,给你一棵树和若干“额外边”,求砍掉一个原树中的边和一个额外边能使这棵树分成至少两块儿的方法。

对于这题,首先对于每一个额外边(x,y),将其在树中的路径(x->y)的每一条的权值都加1。当处理完毕后,我们观察该树,发现:

1、如果有权值为0的边,证明该边是原图的桥;换言之就是一砍跟不加额外边砍树一样绝对会断的(因为没有额外边连接它),这个时候我随便找一个这样的边,再随便挑一个额外边砍就行。方法数为(权值为0边数量)*(额外边数量)

2、如果有权值为1的边,证明该边有且仅有一个额外边“保护”了它,砍掉它再砍掉那个“保护”它的额外边就行了。方法数为(权值为1边数量)

于是我们得出,总数量为(权值为0边数量)*(额外边数量)+(权值为1边数量)。 但是,我们怎么高效地执行“把每一条的权值都加1”这个操作呢?这个时候我们只能搬出大名鼎鼎的——TreeDP!

设F[x]为x到root被加了多少的权值,则当连接一条额外边时,有inc(F[x]); inc(F[y]); dec(F[LCA(x,y),2);(因为在公共祖先上的边是没有被加两次的)。 DP方程为:Dp[now]=sum(Dp[now.son])+F[now]。设一条边为(s->e),则Dp[e]为该边权值。 至此,该问题转化为如何高效地求LCA。

总所周知,LCA的离线可以用Tarjan解决;但是我觉得在线美(这句话被触手牛PIA了),于是我决定尝试使用LCA转化为RMQ。

转化方法可以参见2007年郭华阳神牛的国家集训队论文和黑书P56页。值得一提的是,如果不需要O(n)-O(1)的复杂度的话,可以直接对遍历得到的序列进行RMQ。如果需要O(n)-O(1)的复杂度,则需要额外记录一个深度数组,对深度数组做—+-1RMQ,得到的为序列中的下标。我不会写+-1RMQ...囧

另外就是,遍历层数巨大,需要使用模拟栈。

这道题让我学会了LCA-RMQ„„收获很巨大,感觉很好很强大„„推荐做做这题。

本文是Dai原创文,欢迎转载,但请保留原文(这句话在自恋么) 感谢论文、黑书、触手牛(OTL您是救星啊„„)、父母、电脑„„(我SB了=.=) 以上为口胡,没事请无视。(有事?那也无视嘛)

Points Time Limit: 1000MS

Memory Limit: 65536K Total Submiions: 687 Accepted: 215 Description Let p1, p2, ..., pn be n points on the plane.We have m rules of form pi rel pj , each inform us that the relation rel holds among the locations of points pi and pj on the plane.For example, “pi NE pj” indicates that point pj is located NorthEast of point pi.There are eight different relations {N, E, S, W, NE, NW, SE, SW}, corresponding to the eight directions on the plane.Let (xi, yi) and (xj , yj) be the coordinates of pi, and pj respectively.Then pi rel pj exactly means one of the following, depending on the value of rel: 1.2.3.4.5.6.7.8.N stands for North.This means that xj = xi and yj > yi, E stands for East.This means that xj > xi and yj = yi, S stands for South.This means that xj = xi and yj

NE stands for NorthEast.This means that xj > xi and yj > yi, NW stands for NorthWest.This means that xj yi, SE stands for SouthEast.This means that xj > xi and yj

given rules are satisfied.Input The first line of the input contains a single integer t (1 ≤ t ≤ 20) which is the number of test cases in the input.The first line of each test case contains two integers n (2 ≤ n ≤ 500) which is the number of points and m (1 ≤ m ≤ 10000) which is the number of rules.In each of the following m lines, there is one rule of the form i rel j which means that pi has relation rel with pj.

Output The output contains one line per each test case containing one of the words POSSIBLE or IMPOSSIBLE indicating if the set of points in the test case can be located on the plane according to the given rules.Sample Input 2 3 2 1 N 2 2 N 1 6 6 1 E 2 1 E 3 2 N 4 3 NW 5 4 SW 6 6 NE 5 Sample Output IMPOSSIBLE POSSIBLE

Network Time Limit: 2000MS

Memory Limit: 65536K Total Submiions: 1607 Accepted: 471 Description Yixght is a manager of the company called SzqNetwork(SN).Now she\'s very worried because she has just received a bad news which denotes that DxtNetwork(DN), the SN\'s busine rival, intents to attack the network of SN.More unfortunately, the original network of SN is so weak that we can just treat it as a tree.Formally, there are N nodes in SN\'s network, N-1 bidirectional channels to connect the nodes, and there always exists a route from any node to another.In order to protect the network from the attack, Yixght builds M new bidirectional channels between some of the nodes.As the DN\'s best hacker, you can exactly destory two channels, one in the original network and the other among the M new channels.Now your higher-up wants to know how many ways you can divide the network of SN into at least two parts.Input The first line of the input file contains two integers: N (1 ≤ N ≤ 100 000), M (1 ≤ M ≤ 100 000) — the number of the nodes and the number of the new channels.Following N-1 lines represent the channels in the original network of SN, each pair (a,b) denote that there is a channel between node a and node b.Following M lines represent the new channels in the network, each pair (a,b) denote that a new channel between node a and node b is added to the network of SN.Output Output a single integer — the number of ways to divide the network into at least two parts.Sample Input 4 1 1 2 2 3 1 4 3 4 Sample Output

差分约束 题意:

给出n头牛 输入中有ml行表示牛B至多离牛A D的距离 md行表示牛B至少离牛A D的距离

最后求牛n最多离牛1多少的距离

这个题目是将 x[1]定死为0 求x[n]-x[1] 建图后求最短路径即可; 最短路径求出的解,所有未知数达到最大值。 最长路径求出的解,所有未知数达到最小值。

#include using namespace std; int n,ml,md; struct Edge {

int u,v,w; }edge[20005]; const int INF=100000000; int cnt; int d[1005]; void bellman_ford() {

int i,j;

for(i=2;i

d[1]=0;

for(i=1;i

{

int flag=1;

for(j=1;j

if(d[edge[j].u]+edge[j].w

{

d[edge[j].v]=d[edge[j].u]+edge[j].w;

flag=0;

}

if(flag)break;

}

for(j=1;j

if(d[n]==INF)printf(\"-2\\n\");

else printf(\"%d\\n\",d[n]); } int main() {

int i,a,b,w;

scanf(\"%d%d%d\",&n,&ml,&md);

for(i=1;i

{

scanf(\"%d%d%d\",&a,&b,&w);

edge[++cnt].u=a;

edge[cnt].v=b;

edge[cnt].w=w;

}

for(i=1;i

{

scanf(\"%d%d%d\",&a,&b,&w);

edge[++cnt].u=b;

edge[cnt].v=a;

edge[cnt].w=-w;

}

bellman_ford();

return 0; }

/* 求最短路径 Dijkstra+heap 第一次使用这个。自己写的那个heap不知道为什么有问题,这个用的是上海交大的模板。

*/ #include using namespace std; const int SIZE=300005; const int MAXN=30005; const int INF=100000000; struct Vex {

int id,w,next; }nd[SIZE]; int n,m; int order[MAXN]; int d[MAXN],s[MAXN],len,heap[MAXN]; void Init() {

int end=n+2,i,u,v,w;

memset(nd,-1,sizeof(nd));

for(i=1;i

{

scanf(\"%d%d%d\",&u,&v,&w);

nd[end].next=nd[u].next;

nd[end].w=w;

nd[end].id=v;

nd[u].next=end;

end++;

} } void updata(int r) {

int p,q;

p=order[r];q=p/2;

while(q>0&&d[heap[q]]>d[r])

{

order[heap[q]]=p;

heap[p]=heap[q];

p=q;

q=p/2;

}

heap[p]=r;order[r]=p; } int getmin() {

int p,q,r;

int ret=heap[1];

r=heap[len--];

p=1;q=2;

while(q

{

if(q

if(d[r]>d[heap[q]])

{

order[heap[q]]=p;

heap[p]=heap[q];

p=q;

q=p*2;

}

else break;

}

heap[p]=r;order[r]=p;

return ret; } void Dijkstra(int st,int end) {

int i,j,u;

for(i=1;i

d[st]=0;

len=1;

heap[1]=st;order[st]=1;

while(!s[end])

{

u=getmin();

//printf(\"%d\\n\",u);

s[u]=1;

for(i=nd[u].next;i!=-1;i=nd[i].next)

{

if(s[nd[i].id])continue;

if(d[u]+nd[i].w

{

if(order[nd[i].id]==0)

{

heap[++len]=nd[i].id;

order[nd[i].id]=len;

}

d[nd[i].id]=d[u]+nd[i].w;

updata(nd[i].id);

}

}

}

printf(\"%d\\n\",d[end]); } int main() {

scanf(\"%d%d\",&n,&m);

Init();

Dijkstra(1,n);

cin>>n;

return 0; }

考研数学差分方程

一阶常系数线性差分方程

规矩约束

约束协议书

青海建立国土资源信用约束机制企业信用差不予准入

差分GPS定位原理(小编推荐)

差分信号的分析与LAYOUT(优秀)

国学机也分优良差 您知道吗?

室分质差小区优化项目总结

自由与约束

差分约束
《差分约束.doc》
将本文的Word文档下载到电脑,方便编辑。
推荐度:
点击下载文档
相关专题 差分约束系统 差分
点击下载本文文档