传送门 >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 「差分约束」的更多相关文章

  1. poj1716 Integer Intervals(差分约束)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Integer Intervals Time Limit: 1000MS   Me ...

  2. POJ1201 Intervals (差分约束)

    You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a program that: ...

  3. poj 1716 Integer Intervals(差分约束)

    1716 -- Integer Intervals 跟之前个人赛的一道二分加差分约束差不多,也是求满足条件的最小值. 题意是,给出若干区间,需要找出最少的元素个数,使得每个区间至少包含两个这里的元素. ...

  4. poj 1201 Intervals(差分约束)

    做的第一道差分约束的题目,思考了一天,终于把差分约束弄懂了O(∩_∩)O哈哈~ 题意(略坑):三元组{ai,bi,ci},表示区间[ai,bi]上至少要有ci个数字相同,其实就是说,在区间[0,500 ...

  5. Intervals(差分约束)

    http://poj.org/problem?id=1201 题意:给出N个整数区间[ai,bi],并且给出一个约束ci,( 1<= ci <= bi-ai+1),使得数组Z在区间[ai, ...

  6. POJ 1201 Intervals (经典) (差分约束)

    <题目链接> 题目大意:给你$n$段区间,$a_i,b_i,c_i$ 表示在 $[a_i,b_i]$ 区间内至少要选择$c_i$个点.现在问你在满足这n个条件的情况下,最少要选多少个点? ...

  7. HDU 1384 Intervals【差分约束-SPFA】

    类型:给出一些形如a−b<=k的不等式(或a−b>=k或a−b<k或a−b>k等),问是否有解[是否有负环]或求差的极值[最短/长路径].例子:b−a<=k1,c−b&l ...

  8. 【题解】 POJ 1201 Intervals(差分约束)

    懒得复制,戳我戳我 Solution: 这道题就是一个板子题 抽象成第\(a\)至第\(b\)间选择数的个数为\(c\),我们就可以用前缀和来表示,这样就可以得到不等式\(s[b]-s[a-1]> ...

  9. POJ1201 Intervals 【差分约束】

    题目链接 POJ1201 题解 差分约束 令\(a[i]\)表示是否选择\(i\),\(s[i]\)表示\(a[i]\)的前缀和 对\(s[i] \quad i \in [-1,50000]\)分别建 ...

随机推荐

  1. Ubuntu Server 18.04 修改网路配置

    新的Ubuntu 服务器采用netplan管理网络配置,跟以前的配置有很大的区别. 实际可行的办法是修改/etc/netplan/01-netcfg.yaml文件: sudo vim /etc/net ...

  2. RuntimeError: Model class apps.users.models.User doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.

    报错代码: File "/home/bsodgm/Desktop/Django_projection/mall/apps/users/views.py", line 9, in & ...

  3. 基于Tornado签名cookie源码设计API认证

    想法1 服务端客户端个保存相同的一串字符串,客户端发送API请求时带着这段字符串来我服务端做校验,通过则返回相应数据,否则拒绝访问 弊端 黑客截取到请求信息,可直接会获取到该字符串,想服务端发送请求并 ...

  4. vue的高阶组件

    探索Vue高阶组件 探索Vue高阶组件的使用 Vue高阶组件的使用方法 高阶组件应用-组件重新实例化 深入理解React 高阶组件 探索Vue高阶组件 2018-01-05 探索Vue高阶组件 Vue ...

  5. Python_匿名函数

    匿名函数:为了解决那些功能很简单的需求而设计的一句话函数. 代码如下: 1 正常函数: 2 3 def calc(n): 4 5 return n ** n 6 7 print(calc(10)) 8 ...

  6. Python之参数类型、变量

    一.参数类型 (一)形参与实参 要使用局部变量时,只能通过return的方式返回 def my(name): #函数体 return name my('lrx') #name是形参,lrx是实参 不写 ...

  7. nodejs 中的一些方法

    fs.unlink(path, [callback(err)]) //删除文件操作. //path 文件路径 //callback 回调,传递一个异常参数err. ndoe中解决跨域问题 expres ...

  8. vue路由动态过渡效果

    不多说,直接上代码 import Vue from 'vue' //引入vue import VueRouter from 'vue-router' //引入路由 Vue.use(VueRouter) ...

  9. CMake--变量

    1.一般变量 1)CMake变量引用的方式 使用${}进行变量的引用.例如: ${PROJECT_NAME} #返回项目名称 在 IF 等语句中,是直接使用变量名而不通过${}取值. 2)cmake自 ...

  10. oracle查看表结构命令desc