poj 1201 Intervals(差分约束)
做的第一道差分约束的题目,思考了一天,终于把差分约束弄懂了O(∩_∩)O哈哈~
题意(略坑):三元组{ai,bi,ci},表示区间[ai,bi]上至少要有ci个数字相同,其实就是说,在区间[0,50000]上,每一个三元组表示[ai,bi]之间至少要标记ci个数字,问至少要标记多少个数字。
在学习差分约束的童鞋,建议看一下:09年姜碧野的《SPFA算法的优化及应用》,06年冯威的《浅析差分约束系统》,不过后者看起来较难搞懂,也可以看http://ycool.com/post/m2uybbf 写的很不错。
这里写一下我自己的一点心得:
1、差分约束求的是什么?
这里分为两种:求值,判环。
求值:如这道题所示,最终求的是整个区间上被标记点的最小数量,也就是从起点到终点的最小值,不需考虑判环的情况。更广泛的讲,它可以求解不等式的一组解。
判环:poj 1364判断存不存在,即判正负环。
2、差分约束中的松弛操作
举个最短路的例子,1->2 c=3,1->3 c=1,3->2 c=1,即以1为起点,d[2]>d[3]+w(3,2),可以进行松弛。而三条边本身表示的是:a(2)-a(1)<=3,a(3)-a(1)<=1,a(2)-a(3)<=1,我们是从d[]=INF一路更新过来的,用1->3->2这条边更新1->2,实际上表示的是后两个不等式之和a(2)-a(1)<=2比第一个不等式的约束条件更强。
3、最长路与最短路的区别
两者不仅是在三角不等式的表现形式上不同,具体求解的值也不同。
首先要明确,需要额外的一个限定条件:一般为加入源点s,并建立权值为0的边。对于一个不等式组来说,只要有一组解,那么同时加上定值k,仍然满足约束条件。
最短路:d[v]<d[u]+w(u,v),d[i]初始化为INF,而求解出来的是不等式的最大值。何为最大值?若确定其中一个的值,并非能得到每个数的定值,因为是不等式,所以每个值有其取值范围。这里的最大值就是在源点s的限定条件内,所能够取值的上界。仔细思考,这里的最短路只是满足不等式组条件所找到的解,由于最短路是由大到小做松弛操作,找到的最短路即为“最大”。
最长路:d[v]>d[u]+w(u,v),d[i]初始化为-INF,解释同上。这道题目求的是最小值,自然就只能由最长路求解。
4、关于点的数量
如题目所示{ai,bi,ci},[ai,bi]上至少标记ci个点,可以转化为:s(bi)-s(ai-1)>=ci,注意是(ai-1)而非(ai),由于减1的关系,总点数+1。
在判环过程中,SPFA的判定条件为入队n次,其实质是最短路最长经过(n-1)条边,所以入队n次队列仍不为空,即可以判定存在正负环。当点的总数+1,对应的SPFA判环的条件也就变更为cnt[]>n。
5、关于图的连通性
无论是求值,还是判环,原图不构成强连通的前提下都是不能搜索到每一个点的,所以才出现设立一个源点s的方法。事实上,能够到达各个点,更加实用的是在SPFA初始化时,就把所有点加入队列,并把d[i]全部初始化为0。不仅仅是解决了连通的问题,更是避免了错误——加上一个源点s,使总点数为(n+2),SPFA的判环条件必须为cnt[]>(n+1),这是很容易忽视的问题。
这道题由于存在所谓的隐藏条件0<=s(i)-s(i-1)<=1,据此建图已经能够实现图上的连通。
6、不等式的变形
差分约束解决的是>=和<=的问题,若题目给出的是>k(或<k),需要变形。比如若k是整数,>k等价于>=k+1。
7、无穷解,无解。
http://www.cnblogs.com/zstu-abc/archive/2013/08/18.html
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define clr(a,m) memset(a,m,sizeof(a))
using namespace std; const int MAXN=;
const int INF =MAXN; struct Edge{
int v,c,next;
Edge(){}
Edge(int _v,int _c,int _next):v(_v),c(_c),next(_next){}
}edge[MAXN<<]; int head[MAXN],tol;
int d[MAXN],inq[MAXN]; void init()
{
tol=;
clr(head,-);
} void add(int u,int v,int c)
{
edge[tol]=Edge(v,c,head[u]);
head[u]=tol++;
} void SPFA(int down,int up)
{
queue<int>q;
clr(inq,);
rep(i,down,up)
if(i==down)d[i]=;
else d[i]=-INF;
q.push(down);
inq[down]=true;
while(!q.empty())
{
int u=q.front();q.pop();
inq[u]=false;
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].v;
int c=edge[i].c;
if(d[v]<d[u]+c){
d[v]=d[u]+c;
if(!inq[v]){
q.push(v);
inq[v]=true;
}
}
}
}
} int main()
{
int n,up=,down=MAXN;
int u,v,c;
scanf("%d",&n); init();
rep(i,,n){
scanf("%d%d%d",&u,&v,&c);
add(--u,v,c);
up=max(up,v);
down=min(down,u);
}
rep(i,down,up){
add(i-,i,);
add(i,i-,-);
}
SPFA(down,up); printf("%d\n",d[up]);
return ;
}
poj 1201 Intervals(差分约束)的更多相关文章
- poj 1201 Intervals(差分约束)
题目:http://poj.org/problem?id=1201 题意:给定n组数据,每组有ai,bi,ci,要求在区间[ai,bi]内至少找ci个数, 并使得找的数字组成的数组Z的长度最小. #i ...
- poj 1201 Intervals——差分约束裸题
题目:http://poj.org/problem?id=1201 差分约束裸套路:前缀和 本题可以不把源点向每个点连一条0的边,可以直接把0点作为源点.这样会快许多! 可能是因为 i-1 向 i 都 ...
- POJ 1201 Intervals (差分约束系统)
题意 在区间[0,50000]上有一些整点,并且满足n个约束条件:在区间[ui, vi]上至少有ci个整点,问区间[0, 50000]上至少要有几个整点. 思路 差分约束求最小值.把不等式都转换为&g ...
- POJ 2101 Intervals 差分约束
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 27746 Accepted: 10687 Description You ...
- POJ 1201 Intervals【差分约束】
传送门:http://poj.org/problem?id=1201 题意: 有n个如下形式的条件:,表示在区间[, ]内至少要选择个整数点.问你满足以上所有条件,最少需要选多少个点? 思路:第一道差 ...
- POJ 1201 Intervals (经典) (差分约束)
<题目链接> 题目大意:给你$n$段区间,$a_i,b_i,c_i$ 表示在 $[a_i,b_i]$ 区间内至少要选择$c_i$个点.现在问你在满足这n个条件的情况下,最少要选多少个点? ...
- 【题解】 POJ 1201 Intervals(差分约束)
懒得复制,戳我戳我 Solution: 这道题就是一个板子题 抽象成第\(a\)至第\(b\)间选择数的个数为\(c\),我们就可以用前缀和来表示,这样就可以得到不等式\(s[b]-s[a-1]> ...
- POJ 1201 Intervals(差分约束 区间约束模版)
关于差分约束详情可阅读:http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html 题意: 给定n个区间[L,R], 每个区间至 ...
- poj 1201 Intervals【差分约束+spfa】
设s为前缀和,首先显然的条件是\[ s_{bi}-s_{ai-1}>=c \],然后隐含的是\[ s_i-s_{i-1}>=0 s_i-s_{i-1}<=1 \] 然后根据差分约束, ...
随机推荐
- 3143: [Hnoi2013]游走 - BZOJ
Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点, ...
- map中的erase成员函数用法
转载于 http://www.cnblogs.com/graphics/archive/2010/07/05/1771110.html http://hi.baidu.com/sdkinger/it ...
- 【转载】CCombobox使用大全
一.如何添加/删除Combo Box内容 1. 在Combo Box控件属性的Data标签里面添加,一行表示Combo Box下拉列表中的一行.换行用ctrl+回车. 2. 在程序初始化时动态添加 如 ...
- unity3d 射线扫描 忽略图层
原地址:http://blog.csdn.net/w88193363/article/details/38331205 函数说明 static RaycastHit2D[] RaycastAll(Ve ...
- java基础知识回顾之javaIO类--File类应用:过滤器接口FilenameFilter和FileFilter
FilenameFilter和FileFilter都是用来过滤文件,例如过滤,以.jpg或者.java结尾的文件,通过看他们的源码:通过使用File类中String[] list(FilenameFi ...
- POJ 1125 Stockbroker Grapevine(floyd)
http://poj.org/problem?id=1125 题意 : 就是说想要在股票经纪人中传播谣言,先告诉一个人,然后让他传播给其他所有的经纪人,需要输出的是从谁开始传播需要的时间最短,输出这个 ...
- @JsonFormat时间不对
实际时间为:2015-07-06 20:20:23 1. @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date ...
- 单例模式与Android
http://blog.csdn.net/ljianhui/article/details/29275655 多线程下的单例模式是不安全的 Android中的单例模式 Android中存在着大量的单例 ...
- PCB走线角度选择 — PCB Layout 跳坑指南
现在但凡打开SoC原厂的PCB Layout Guide,都会提及到高速信号的走线的拐角角度问题,都会说高速信号不要以直角走线,要以45度角走线,并且会说走圆弧会比45度拐角更好.狮屎是不是这样?PC ...
- lua string函数
lua的string函数: 参数中的index从1开始,负数的意义是从后开始往前数,比如-1代表最后一个字母 对于string类型的值,可以使用OO的方式处理,如string.byte(s.i)可以被 ...