☆ [POJ1021] Intervals 「差分约束」
传送门 >Here<
题意:给出N段区间,并告诉你每段区间里有几个数(一个位置只能放一个数) 问总共至少有几个数
解题思路
差分约束题,本蒟蒻也是第一次做差分约束题……
所谓差分约束,常常是通过最短路(或最长路)来解决一些约束问题,例如不等式组
举个例子:$$x1 -x2 \leq a1 (1)$$$$x2 -x3 \leq a2 (2)$$$$x1 -x3 \leq a3 (3)$$求解$x1-x3$的解集
则我们可以让1~2连一条长度为a1的有向边,2~3连一条长度为a2的有向边,1~3连一条长度为a3的有向边
我们会发现$(1)+(2)$可以得到$x1 - x3 \leq a1 + a2$(利用了不等式之间相加的定理),因此得到一组不等式组$$x1 - x3 \leq a1 + a2$$$$x1 -x3 \leq a3 (3)$$
而最终由于是小于等于的约数,解集应当取$Min\{ a1+a2, a3 \}$
为什么可以转化为最短路问题呢?考虑一条路径,对于所有非起点且非终点的点,与其相邻的路径上的两个点对应了两条路径,不妨设为$a-s,s-b$,则当这两个不等式相加时,中介点$s$一定会被消掉。宏观来看,一条路径上所有非起点终点的点都将为被抵消掉。因此最后只剩下路径的头尾了。而要求解集,如果是$<$,则应该取最小值,也就是最短路了。
以上是差分约束的基本概念。那么回到这道题来,好像和差分约束没什么关系?
光看好像是没什么关系。由于是考虑区间内数的个数,不妨设想有一个前缀和数组s,这样$[a_i, b_i]$至少有$c_i$个元素就可以表示成$s[b_i] - s[a_i-1] >= c[i]$,我们会得到若干个这样的不等式,就可以做差分约束了——然而值得注意的是,刚才的例子里是小于等于,而这里是大于等于。所以这里的解集应当取到最大,所以求的是最长路而不是最短路
真的仅仅只是这样吗?我们忽略了题目给的一个条件——每个位置只能放一个数,所以我们的约束条件少了,要加上对于每一个位置i,$s[i]-s[i-1] \geq 0, s[i]-s[i-1] \leq 1$(其实$s[i]-s[i-1]$)就是i这个位置的数的个数,不是0就是1. 对于小于等于的情况,同时乘以-1转换成大于等于的形式,$s[i-1]-s[i] \geq -1$即可
code
注意Dijkstra是不能做负权的(有$s[i-1]-s[i] \geq -1$的存在),所以用SPFA
/*By QiXingzhi*/
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define r read()
#define Max(a,b) (((a)>(b)) ? (a) : (b))
#define Min(a,b) (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
const int MAXN = ;
const int INF = ;
inline int read(){
int x = ; int w = ; register int c = getchar();
while(c ^ '-' && (c < '' || c > '')) c = getchar();
if(c == '-') w = -, c = getchar();
while(c >= '' && c <= '') x = (x << ) +(x << ) + c - '', c = getchar();
return x * w;
}
int N,L,R;
int a,b,c,d[MAXN],vis[MAXN];
int first[MAXN*],nxt[MAXN*],to[MAXN*],cost[MAXN*],num_edge;
queue <int> q;
inline void add(int u, int v, int w){
// printf("%d->%d (%d)\n", u,v,w);
to[++num_edge] = v;
cost[num_edge] = w;
nxt[num_edge] = first[u];
first[u] = num_edge;
}
inline void SPFA(int s){
for(int i = ; i <= N; ++i) d[i] = -INF;
d[s] = ;
q.push(s);
int u, v;
while(!q.empty()){
u = q.front();
q.pop();
vis[u] = ;
for(int i = first[u]; i; i = nxt[i]){
v = to[i];
if(d[u] + cost[i] > d[v]){
d[v] = d[u] + cost[i];
if(!vis[v]){
vis[v] = ;
q.push(v);
}
}
}
}
}
inline void Init(){
memset(vis,,sizeof(vis));
memset(first,,sizeof(first));
memset(nxt,,sizeof(nxt));
memset(to,,sizeof(to));
memset(cost,,sizeof(cost));
}
int main(){
// freopen(".in","r",stdin);
while(scanf("%d",&N) == ){
L = N+, R = -;
Init();
for(int i = ; i <= N; ++i){
a=r,b=r,c=r;
add(a, b+, c);
L = Min(L, a);
R = Max(R, b+);
}
for(int i = ; i <= R; ++i){
add(i+, i, -);
add(i, i+, );
}
SPFA(L);
// printf("R+1 = %d L+1 = %d\n",R+1,L+1);
printf("%d\n", d[R]);
}
return ;
}
☆ [POJ1021] Intervals 「差分约束」的更多相关文章
- poj1716 Integer Intervals(差分约束)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud Integer Intervals Time Limit: 1000MS Me ...
- POJ1201 Intervals (差分约束)
You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: ...
- poj 1716 Integer Intervals(差分约束)
1716 -- Integer Intervals 跟之前个人赛的一道二分加差分约束差不多,也是求满足条件的最小值. 题意是,给出若干区间,需要找出最少的元素个数,使得每个区间至少包含两个这里的元素. ...
- poj 1201 Intervals(差分约束)
做的第一道差分约束的题目,思考了一天,终于把差分约束弄懂了O(∩_∩)O哈哈~ 题意(略坑):三元组{ai,bi,ci},表示区间[ai,bi]上至少要有ci个数字相同,其实就是说,在区间[0,500 ...
- Intervals(差分约束)
http://poj.org/problem?id=1201 题意:给出N个整数区间[ai,bi],并且给出一个约束ci,( 1<= ci <= bi-ai+1),使得数组Z在区间[ai, ...
- POJ 1201 Intervals (经典) (差分约束)
<题目链接> 题目大意:给你$n$段区间,$a_i,b_i,c_i$ 表示在 $[a_i,b_i]$ 区间内至少要选择$c_i$个点.现在问你在满足这n个条件的情况下,最少要选多少个点? ...
- HDU 1384 Intervals【差分约束-SPFA】
类型:给出一些形如a−b<=k的不等式(或a−b>=k或a−b<k或a−b>k等),问是否有解[是否有负环]或求差的极值[最短/长路径].例子:b−a<=k1,c−b&l ...
- 【题解】 POJ 1201 Intervals(差分约束)
懒得复制,戳我戳我 Solution: 这道题就是一个板子题 抽象成第\(a\)至第\(b\)间选择数的个数为\(c\),我们就可以用前缀和来表示,这样就可以得到不等式\(s[b]-s[a-1]> ...
- POJ1201 Intervals 【差分约束】
题目链接 POJ1201 题解 差分约束 令\(a[i]\)表示是否选择\(i\),\(s[i]\)表示\(a[i]\)的前缀和 对\(s[i] \quad i \in [-1,50000]\)分别建 ...
随机推荐
- 实现多个标签页之间通信的几种方法(sharedworker)
效果图.gif prologue 之前在网上看到一个面试题:如何实现浏览器中多个标签页之间的通信.我目前想到的方法有三种:使用websocket协议.通过localstorage.以及使用html ...
- 怎么用npm发布一个包,详细教程
我们已经实现了路由的自动化构建,但是我们可以看到,一大串代码怼在里面.当然你也可以说,把它封装在一个JS文件里面,然后使用require('./autoRoute.js')给引入进来,那也行.但是,为 ...
- Python—元类
什么是元类? 元类是类的类,是类的模板 元类是用来控制如何创建类的,正如类是创建对象的模板一样,而元类的主要目的是为了控制类的创建行为 元类的实例化的结果为我们用class定义的类,正如类的实例为对象 ...
- Redis服务端的搭建(初级)
前方低能,仅适合入门级菜鸟阅读,大神大牛通通闪开! 前言:redis经常被用来做缓存(原因自行科普),基于学习的需要自己搭建了一个redis服务器,考虑到项目的分布式部署,所以前期开始的时候,redi ...
- Mysql 中的MVCC原理,undo日志的依赖
一. MVCC 原理了解 原文点击:MVCC原理浅析 读锁: 也叫共享锁.S锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的 ...
- springBoot项目启动类启动无法访问
springBoot项目启动类启动无法访问. 网上也查了一些资料,我这里总结.下不来虚的,也不废话. 解决办法: 1.若是maven项目,则找到右边Maven Projects --->Plug ...
- 自己实现数据结构系列三---Stack
一.代码部分 1.定义接口 public interface Stack<E> { int getSize(); boolean isEmpty(); void push(E e); E ...
- 解决Window安全中心对Kitematic-0.17.3-Ubuntu.zip提示病毒,但无法删除的问题。
Trojan:JS/Tisifi.B 类型:特洛伊木马 containerfile: C:\Users\Administrator\Desktop\Kitematic-0.17.3-Ubuntu.zi ...
- java注解和自定义注解的简单使用
前言 在使用Spring Boot的时候,大量使用注解的语法去替代XML配置文件,十分好用. 然而,在使用注解的时候只知道使用,却不知道原理.直到需要用到自定义注解的时候,才发现对注解原理一无所知,所 ...
- [转帖]Docker的数据管理(volume/bind mount/tmpfs)
Docker(十五)-Docker的数据管理(volume/bind mount/tmpfs) https://www.cnblogs.com/zhuochong/p/10069719.html do ...