☆ [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]\)分别建 ...
随机推荐
- heb Daz
Asatras soi bib Daz! gos la haik ri, dewoa gos mi haik quri. soi Fong d cuup va ti Chusan, imps Dabo ...
- P66 整环的零元
R/I=0的零因子是0+I吗? 如果不是,那请问R/I的零因子是什么呢? R/I没有零因子 R/I的零元 是I中的元素定义的等价类 么 a是理想I的元素,自然也是R的元素
- Python_字符串初识及操作
字符串初识及操作 str 'alex'.'1235443543'.'[1,2,3]'.可存放少量数据. 索引.切片.步长 索引编号 正向索引 'python' 012345 'p'的正向索引编号为0 ...
- [2017BUAA软工助教]个人项目小结
2017BUAA个人项目小结 一.作业链接 http://www.cnblogs.com/jiel/p/7545780.html 二.评分细则 0.注意事项 按时间完成并提交--正常评分 晚交一周以内 ...
- PHP开发编码规范
(转载:https://blog.csdn.net/alexdream/article/details/2213313) 这些年来多从事Linux下PHP和C相关的开发,带过很多项目和团队,下面是根据 ...
- 6-1 Quantifiers
1 Quantifiers are used to describe the number or amount of something. Certain quantifiers are used w ...
- 6 Prefer and Would rather
1 prefer 使用 "prefer" 用来表明通常喜欢某件事甚于另一件事.说话者喜欢打高尔夫球更甚于喜欢打网球."prefer" 的后面可以接名词(&quo ...
- Linux 下面RPM 安装的SQLSERVER 修改字符集的方法
1. 自己还是太low 2. 遇到问题 先 -h 处理 3. 发现登录报错, 怀疑是字符集的问题: 4. 计划是修改字符集 到 自己的环境可用的状态 使用命令 /opt/mssql/bin/mssql ...
- 【学亮IT手记】Java 8新特性实例介绍
java8,也称为jdk1.8,于2014.03.18日发布,它支持函数式编程,新的js引擎,新的日期API,新的Stream Api等. 我们主要讨论以下几个新特性: ①Lambda表达式. 允许把 ...
- nodejs 利用zip-local模块压缩文件夹
var zipper = require("zip-local"); zipper.sync.zip("./folder").compress().save(& ...