区间选点 差分约束

题意:

给定一个数轴上的 n 个区间,要求在数轴上选取最少的点使得第 i 个区间 [ai, bi] 里至少有 ci 个点。使用差分约束系统的解法解决这道题。

Input
输入第一行一个整数 n 表示区间的个数,接下来的 n 行,每一行两个用空格隔开的整数 a,b 表示区间的左右端点。1 <= n <= 50000, 0 <= ai <= bi <= 50000 并且 1 <= ci <= bi - ai+1。
Output
输出一个整数表示最少选取的点的个数

Sample Input
5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1

Sample Output
6


思路:

题意需要满足[ai, bi]区间内至少有ci个整数点,我们可以采取前缀和的思想设立sum[i]表示[0,i]之间选点的个数,因此题目的要求则可以转化为sum[bi] - sum[ai]>=ci。于是题目给的所有条件都可以转化为这种不等式,构成了差分约束系统。

求解差分约束系统可以转化为最短路或是最长路问题。若是不等式约束类似为xj - xi<=ck,设x[j] = dis[j],x[i] = dis[i],ck = w(i,j),于是这个式子可以转化为dis[j]<=dis[i] + w(i,j),即最短路的松弛操作,原式子的松弛操作实际上也非常好理解,举例:若是我们依据约束不等式组求得两个不等式x[i] - x[j]<=4,x[i] - x[j]<=5,类似松弛操作我们可以将不等式缩为x[i] - x[j]<=4。同理若是不等式约束类似为xj - xi>=ck,那么则是求最长路。

落实到题目中而言,我们可以归纳差分约束系统可以转化为最短路时是求上限,即最多什么,而转化为最长路则是最少什么。

由于在求解最短路的过程中出现存在负环或者终点不可达的情况,那么在求解差分约束的过程中也会存在这样的问题 。
存在负环 :如果路径中存在负环则表现为最短路的无限小,即最短路不存在 在不等式约束上表现为𝑥i−𝑥1≤𝑇中的T为无限小,得出的结论就是𝑥i的结果不存在 。可以通过Bellman算法或者队列优化的Bellman算法(SPFA)来判断负环是否存在 ,终点不可达这种情况表明变量𝑥i与变量1 之间没有约束关系 。𝑥i的结果可以是无限大,对应代码中为dis[i]=inf。

这道题目是为了求至少要多少个点,因此采用最长路的写法。上述的sum[i]落实到代码中实际上是dis[i],即某点距离起始点之间的距离。

注意我们建图时,除了题目之间给的边,还需要外加一些边

for (int i = 0; i < Max; i++)
	{
   
		add(i, i + 1, 0);  //为了让全连起来
		add(i + 1, i, -1);
	}

增加i到i+1之间权值为0的边是为了让图连起来,并且不会增加新的距离,而增加i+1到i之间权值为-1的边是为了实现能反走,因为会存在这样的情况,反走一点,再走题目给的边距离更长。例如题目给了区间[1, 9]要取8个点,区间[7, 15]要取4个点,若是不添加返回的点则最长距离为8,若是添加了,则为9。


总结:

差分约束的思想非常的巧妙,硬生生将一组不等式求解转化为了单元最短路或是最长路距离求解。但是求解的过程中也可能出现不存在解的情况,对应图中就是出现负环或没有边,因此可以采取通过Bellman算法或者队列优化的Bellman算法(SPFA)来判断负环是否存在 。


代码

#define _CRT_SECURE_NO_DEPRECATE 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值