差分约束
差分约束就是求解一系列不等式,然后根据这些约束求出一个最大值或者最小值,然后这一系列的不等式又很神奇的可以都当成一个图来解,然后剩下的就是求最短路径或者最长路径,详细的推荐一下博客
差分约束系统
深夜写算法之差分约束
这两篇文章中都有差分约束的套路,我这里再截一张图,方便日后复习,
链式前向星
之前我在记录最短路径问题的时候遇到过这个记录图的方法,感觉很是神奇,只不过不知道叫什么名字,今天终于认到他了,这里再链式前向星的代码
typedef struct Edge{
int dest, value, next;
}Edge;
Edge edge[maxn];
int edgeindex[maxn], k = 1;
void addedge(int sour, int dest int value){
edge[k].dest = dest;
edge[k].value = value;
edge[k].next = edgeindex[sour];
edgeindex[sour] = k ++;
}
链式前向星用来存储系数图的时候就比邻接表舒服多了,而且在遍历的时候更快
判环
这里就是spfa判环,就是通过一个数组,这个数组记录每个点进入队列的次数,是进入队列的次数, 不是更新这个点的数据,因为有可能两个点之间有很多边。如果进队列的次数,大于总的点数,就形成了负环或者正环。
poj3169
这是差分约束的入门题,但我还是整了好久,关键就是处理这些不等式,可能是好久没有碰过不等式。主要是分成两部分讨论,先是两头牛a , b之间不能分开m米,直接就变成不等式b - a <= m
,然后就是第二部分,两头牛a, b之间必须隔开m米,就是b - a >= m
,但是这种形式有问题,因为题目要求最大值,所以不等式都应该是小于等于某一个数,要不然就是无穷大,所以这个不等式就是要变成a - b <= -m
, 然后就是隐藏条件了从1 到 ni+1 - i <= m
,之所以要这个隐藏条件,就是要把所有的不等式都连起来,我又是怎么想到这个隐藏条件的喃?我其实用的是最笨的办法,就是分类讨论,然后才慢慢把这道题整透。。。
其实难就难在建模,然后就是用spfa套就行了
poj1201 poj1716
这两套题很相近,就是区间中最少要找几个元素,我这里有一点小处理,就是所有后界加一然后就是根据输入有b - a >= m
,然后就是加隐藏条件,i+1 - i >= 1
poj1364
这个国王真的弹。然后就是把这些数列s {a1, a2, a3, … an}, 变成{a1, a1+a2, a1+a2+a3,…},然后再根据输入建模,然后就是判断是否有环,但是因为数列s中每一个元素,不确定到底是正还是负,所以没有隐含条件可以用,因为毕竟不是递增也不是递减,所以所有的不等式有可能根本就不能建成一张图,所以如果只是从某一个点除法判断的话很有可能不能把所有的不等式都考虑进来,所以我就是通过从每一个点除法,都不停的判断是某会成环
poj1932
这个有点问题就是有可能需要不停循环的多次,“积蓄力量”, 然后才能继续往下走,所以再判断环的时候,就不能向上面一样判断环的方法,这里要把判断进队列的次数设置多一点