这道题算作是差分约束模板题了, 关于差分约束,我强推这位大佬的博客。https://blog.csdn.net/consciousman/article/details/53812818
里面博客这段话就是解决这些题目的精髓了;
(下面这段话是上面博客里面的)
/*****************************************************************************/
1、 根据条件把题意通过变量组表达出来得到不等式组,注意要发掘出隐含的不等式,比如说前后两个变量之间隐含的不等式关系。
2、 进行建图:
首先根据题目的要求进行不等式组的标准化。
(1)、如果要求取最小值,那么求出最长路,那么将不等式全部化成xi – xj >= k的形式,这样建立j->i的边,权值为k的边,如果不等式组中有xi – xj > k,因为一般题目都是对整形变量的约束,化为xi – xj >= k+1即可,如果xi – xj = k呢,那么可以变为如下两个:xi – xj >= k, xi – xj <= k,进一步变为xj – xi >= -k,建立两条边即可。
(2)、如果求取的是最大值,那么求取最短路,将不等式全部化成xi – xj <= k的形式, 这样建立j->i的边,权值为k的边,如果像上面的两种情况,那么同样地标准化就行了。
(3)、如果要判断差分约束系统是否存在解,一般都是判断环,选择求最短路或者最长路求解都行,只是不等式标准化时候不同,判环地话,用spfa即可,n个点中如果同一个点入队超过n次,那么即存在环。
值得注意的一点是:建立的图可能不联通,我们只需要加入一个超级源点,比如说求取最长路时图不联通的话,我们只需要加入一个点S,对其他的每个点建立一条权值为0的边图就联通了,然后从S点开始进行spfa判环。最短路类似。
3、 建好图之后直接spfa或bellman-ford求解,不能用dijstra算法,因为一般存在负边,注意初始化的问题。
/*************************************************************************************/
然后我们联系到这题目中,由于题目只是要求我们判断能否存在,所以我们化简不等式的时候可以选择化大于号也可以等于号;
大于号的话就是
f[i]:表示i农场里面的作物
- f[a] -f[b]>=c;
- f[b]-f[a]>=-c;
- f[a]-f[b]>=0;
- f[b]-f[a]>=0;
也可以把上面式子以为变成全部小于的。
对于上面式子,用博客里面的做法,就是
- b连a,权值是c
- a连b,权值是-c
- a连b,权值是0
- b连a,权值是0
然后跑最长路。小于号的就边的权和方向改成小于号的形式在跑最短路。
然后由于只是需要判断是否成环,就用dfs版的spfa最快。
下面是代码
#include
#include
#include
#include
#include
#include
#include