差分约束系统

前言

这是一篇学习小记。(如果你很赶时间直接跳过前言)
由于本蒟蒻之前没有接触过这类题目,所以最近被一道题虐了一下,然后学习了。
其实这个名字很耳熟,只是在我小的时候,听说了,却没有去学习。
好吧,其实现在才这个东西是个非常基础的东西,但是它的思路极为巧妙。

例题

首先来看一道题。

有一段长度为n的序列,点分为特殊点和一般点。有q个提示,提示形如(x,y,c)的三元组,表示序列中的区间[x,y]中至少有c个特殊点。提示保证特殊点的分配方案唯一。现在要求哪些点是特殊点。

差分约束系统

我们设 s[i] 表示 [1,i] 中有 s[i] 个特殊点。
那么我们的提示 (x,y,c) 可以转换为这样的约束: s[y]s[x1]c
当然,还有一些隐含的约束条件:
i[1,n],0s[i]s[i1]1
具体如何约束,可以这样构图:
对于三元组,令 x1 y 连一条长度为c的边;
对于隐含约束,令 i1 i 连一条长度为0的边, i i1连一条长度为 1 的边。
然后跑一边最长路,求出了所有的 s ,若s[i]s[i1]=1,则说明 i 是一个特殊点,其实s就相当于普通最短路中的 dis
至于这样做的原理,可以用最短(其实可能是最长)路的性质来解释。
设有两个点 u,vG dis[u] 表示源点到 u 的最距离,w(u,v)表示 (u,v) 的边权。
那么

dis[u]dis[v]+w(u,v)   (1)

恒成立。
而我们的约束化成一般形式即
s[u]s[v]c

移项,恰好与 1 式等价。所以这就是我们将c作为 w(u,v) 的原因。
当然具体题目中因题而定到底是最短路还是最长路。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值