PKU 1201 Intervals(差分约束系统+Spfa)
题目大意:原题链接
构造一个集合,这个集合内的数字满足所给的n个条件,每个条件都是指在区间[a,b]内至少有c个数在集合内。问集合最少包含多少个点。即求至少有多少个元素在区间[a,b]内。
解题思路:
首先假设s[i]表示从0到i中有s[i]个数属于这个序列。
1. 开始我用每个整数(1,2,...)当做图的结点,添加边就是Add(u,v,w),写出来之后发现连题目的样例数据都输出错误,输出结果为8.
2. 后来发现这样是错误的,比如有两个约束条件分别为:1 3 2, 3 6 2;那么按照上面的思路添加这两条边<1,3>=2,<3,6>=2;后又可以得到边<1,6>=4,意思是在线段[1,6]上至少要选4个点,而实际上不是的,应该是至少要选3个点就够了。问题出哪呢??因为线段[1,3]和[3,6]有一个公共点3.
3. 所以要换一种方式建图,对于一个条件(u,v,w)实际上表示在开区间(u-0.5,v+0.5)上至少选w整数点,但是又不能把3.5,4.5,5.5...这样的小数当做图的结点啊!再换一种,用左闭右开区间[u,v+1),因为取的是整数点,所以意义和闭区间[u,v]一样,这样,对于每个限制条件(u,v,w)就可以添加边<u,v+1>=w;即Add(u,v+1,w).
4.但是这题和上一题PKU3169又有点不同,上一题奶牛节点编号是连续的,而这一题节点编号是不连续的,所以要学会挖掘题目中的隐含条件。首先,对于每个描述,都可以得到一个方程s[v]-s[u]>=w,同时由于每个数至多取一次,那么有0<=s[i]-s[i-1]<=1,写成统一的形式(即不等式的朝向相同)即为:s[v]-s[u]>=w; s[i]-s[i-1]>=0; s[i-1]-s[i]>=-1.这样节点编号就连续了,接下来采用和PKU3169同样的方法建图即可。
注意:此题跑的是最长路 ; queue<int> que;语句可以定义为全局变量或者定义在Dijkstra(int u)内部。说来也奇怪,之前做Vjudge上的一道题时,该语句非得定义在函数Dijkstra(int u)内部,否则一直WA,当时也是气的不行。
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define maxn 50010
#define inf 0x3f3f3f3f
using namespace std;
int m,u,v,w,s,t,tot=;
bool vis[maxn];
int d[maxn],head[maxn];
struct Edge
{
int to,wt;
int next;
}e[*maxn]; void Add(int u,int v,int w)
{
e[tot].to=v;
e[tot].wt=w;
e[tot].next=head[u];
head[u]=tot++;
}
queue<int> que;
void Dijkstra(int u)
{
for(int i=s;i<=t;i++)
d[i]=i==u?:-inf;
que.push(u);
while(!que.empty()){
u=que.front();
que.pop();
for(int i=head[u];i!=-;i=e[i].next){
int v=e[i].to;
int w=e[i].wt;
if(d[v]<d[u]+w){//d[u]!=-inf可有可无
d[v]=d[u]+w;
que.push(v);
}
}
}
} int main()
{
while(scanf("%d",&m)!=EOF){
s=inf,t=-inf;
memset(d,,sizeof(d));
memset(e,,sizeof(e));
memset(vis,,sizeof(vis));
memset(head,-,sizeof(head));
for(int i=;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
Add(u,v+,w);
s=min(u,s),t=max(t,v+);
}
for(int i=s;i<t;i++){
Add(i,i+,);
Add(i+,i,-);
}
Dijkstra(s);
printf("%d\n",d[t]);
}
}
加上vis[maxn]数组标记后好像也并没有加快,不知道是测试数据不够大还是根本就不能节省时间。注意Dijkstra(int u)函数中vis[maxn]的位置非常重要;
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define maxn 50010
#define inf 0x3f3f3f3f
using namespace std;
int m,u,v,w,s,t,tot=;
bool vis[maxn];
int d[maxn],head[maxn];
struct Edge
{
int to,wt;
int next;
}e[*maxn]; void Add(int u,int v,int w)
{
e[tot].to=v;
e[tot].wt=w;
e[tot].next=head[u];
head[u]=tot++;
}
queue<int> que;
void Spfa(int u)
{
for(int i=s;i<=t;i++)
d[i]=i==u?:-inf;
que.push(u);
while(!que.empty()){
u=que.front();
que.pop();
vis[u]=;
for(int i=head[u];i!=-;i=e[i].next){
int v=e[i].to;
int w=e[i].wt;
if(d[v]<d[u]+w){//d[u]!=-inf可有可无
d[v]=d[u]+w;
if(vis[v]) continue;
vis[v]=;
que.push(v);
}
}
}
} int main()
{
while(scanf("%d",&m)!=EOF){
s=inf,t=-inf;
memset(d,,sizeof(d));
memset(e,,sizeof(e));
memset(vis,,sizeof(vis));
memset(head,-,sizeof(head));
for(int i=;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
Add(u,v+,w);
s=min(u,s),t=max(t,v+);
}
for(int i=s;i<t;i++){
Add(i,i+,);
Add(i+,i,-);
}
Spfa(s);
printf("%d\n",d[t]);
}
}
PKU 1201 Intervals(差分约束系统+Spfa)的更多相关文章
- POJ 1201 Intervals (差分约束系统)
题意 在区间[0,50000]上有一些整点,并且满足n个约束条件:在区间[ui, vi]上至少有ci个整点,问区间[0, 50000]上至少要有几个整点. 思路 差分约束求最小值.把不等式都转换为&g ...
- 差分约束系统 + spfa(A - Layout POJ - 3169)
题目链接:https://cn.vjudge.net/contest/276233#problem/A 差分约束系统,假设当前有三个不等式 x- y <=t1 y-z<=t2 x-z< ...
- 【差分约束系统/SPFA】POJ3169-Layout
[题目大意] n头牛从小到大排,它们之间某些距离不能大于一个值,某些距离不能小于一个值,求第一头牛和第N头牛之间距离的最大值. [思路] 由题意可以得到以下不等式d[AL]+DL≥d[BL]:d[BD ...
- BZOJ 2330 [SCOI2011]糖果 ——差分约束系统 SPFA
最小值求最长路. 最大值求最短路. 发现每个约束条件可以转化为一条边,表示一个点到另外一个点至少要加上一个定值. 限定了每一个值得取值下界,然后最长路求出答案即可. 差分约束系统,感觉上更像是两个变量 ...
- Intervals(差分约束系统)
http://poj.org/problem?id=1201 题意:给定n个整数闭区间[a,b]和n个整数c,求一个最小的整数集合Z,满足Z里边的数中范围在闭区间[a,b]的个数不小于c个. 思路:根 ...
- poj 1201/zoj 1508 intervals 差分约束系统
// 思路 : // 图建好后 剩下的就和上一篇的 火烧连营那题一样了 求得解都是一样的 // 所以稍微改了就过了 // 最下面还有更快的算法 速度是这个算法的2倍#include <ios ...
- POJ1201 Intervals差分约束系统(最短路)
Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a p ...
- 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 都 ...
随机推荐
- ES 中的 POST 和 PUT 的区别
0.什么是Restful架构 比较难说清楚,这部分大雾状态,引ruanyf 理解RESTful架构 的几句总结吧: Fielding将他对互联网软件的架构原则,定名为REST,即Representat ...
- javascript实现打印功能
<input name="b_print" type="button" class="ipt" onClick="print ...
- Frameset 两页面互调控件技术案例
总共包含三个页面(Html),分别为Parent.Html.ChildA.Html.ChildB.Html Parent.Html页面代码 <frameset cols="50%,*& ...
- ETL概念,ETL流程
ETL是将业务系统的数据经过抽取.清洗转换之后加载到数据仓库的过程,目的是将企业中的分散.零乱.标准不统一的数据整合到一起,为企业的决策提供分析依据. ETL是BI项目重要的一个环节. 通常情况下,在 ...
- galera安装之编译安装xtrabackup 2.2.11
----1.编译安装percona-xtrabackup yum -y install cmake gcc gcc-c++ libaio libaio-devel automake autoconf ...
- Linux中使用SecureCRT上传、下载文件命令sz与rz用法实例
来自:http://www.jb51.net/LINUXjishu/163820.html 其中,对于sz和rz的理解与记忆我用了如下的方法(因为很多时候容易搞混):sz中的s意为send(发送),告 ...
- JSP内置对象——out,get与post
JSP内置对象是Web容器创建的一组对象,不使用new关键字就可以的内置对象.JSP九大内置对象:out,request,response,session,application,page,pageC ...
- Oracle 查询表信息(字段+备注) .
var t= CardService.GetInstance().test("900000000233"); foreach (DataRow row in ...
- LeetCode 笔记系列一 Median of Two Sorted Arrays
题目:There are two sorted arrays A and B of size m and n respectively. Find the median of the two sort ...
- Python--进阶处理7
# ====================第七章:函数========================= # 为了能让一个函数接受任意数量的位置参数,可以使用一个* 参数# 为了接受任意数量的关键字 ...