关于差分约束
差分约束:求不等式组的一组可行解(xi <= xj + c)
分析一下:
对于每个不等式,我们类比求最短路时的不等式;
如果存在最短路(j->i有一条c的边),因为如果dis[i]>dis[j]+c,那么我们要更新;
所以如果存在最短路,则最后一定满足 dis[i] <= dis[j]+c;
(每个不等式相当于是对边进行了限制)
所以对于每个不等式xi <= xj + c,我们抽象成 j->i有一条c的边;
然后跑单源最短路,如果有最短路,则说明有一组可行解。
总结差分约数:
1. 对于不等式组(xi <= xj + c),类比最短路最后一定满足dis[i] <= dis[j]+c
所以抽象成(j->i有一条c的边),找源点,跑最短路;
若有负环<=>无解;若无负环<=>dis[i]就是xi的一个可行解
2. 对于不等式组(xi >= xj + c),类比最长路最后一定满足dis[i] >= dis[j]+c
所以抽象成(j->i有一条c的边),找源点,跑最长路;
若有正环<=>无解;若无正环<=>dis[i]就是xi的一个可行解
1和2是对称的(其中c是正负数都无所谓).
求解步骤:
1. 看问的是什么:(求最值时看细节的5)
求最小值:所以是 xi >= xj+c ;在所有下界中取最大值,所以跑最长路;
求最大值:所以是 xi <= xj+c ;在所有上界中取最小值,所以跑最短路;
2. 分析题目,根据问题,抽象 列出不等式组(要思考当前的的不等式组够不够:是否满足当前的不等式组就能有解?)
3. 根据不等式建边(xi <= xj + c) <=> (j->i连一条c的边)
4. 找(建立)超级源端,该点要能遍历到所有边
5. 从源点跑最短路(最长路)
6. 若有负(正)环<=>无解;若无负(正)环<=>dis[i]就是xi的一个可行解
细节注意:
1. 源点条件:从源点一定要能到达所有的边(若有到不了的边,则不会考虑该边,最终结果可能不满足该边的要求)
2. 优化细节:t了的话把queue改成stack,正常写的时候还是用queue
3. 注意题目问的是啥,比如问2到n的距离,那么你就应该从2开始跑spfa, 跑完dis[n]=inf表示n没有约束
4. 判负环一定要从超级源点开始跑。
5. 重点:求最值时一定有一个固定的式子,类似xi >= c (xi <= c).
如何转换成一般的式子呢?我们建立超级源点x0,那么原式就变成:
xi >= x0 + c (xi <= x0 + c),然后建边就行。