POJ3162 Walking Race(树形DP+尺取法+单调队列)
题目大概是给一棵n个结点边带权的树,记结点i到其他结点最远距离为d[i],问d数组构成的这个序列中满足其中最大值与最小值的差不超过m的连续子序列最长是多长。
各个结点到其他结点的最远距离可以用树形DP解决,HDU2196。
而那个最长的连续子序列可以用单调队列求。。搞了挺久看了解法体会了下。。简单来说就是尺取法,用两个指针[i,j]表示区间,j不停+1往前移动,然后用两个单调队列分别同时更新区间最小值和最大值,再看两个队列队首的最值差是否大于m,是的话出队并调整i值,最后用j-i+1更新答案。
当然尺取法+RMQ也是OK的。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF (1LL<<60)
#define MAXN 1000111
struct Edge{
int v,w,next;
}edge[MAXN];
int NE,head[MAXN];
void addEdge(int u,int v,int w){
edge[NE].v=v; edge[NE].w=w; edge[NE].next=head[u];
head[u]=NE++;
}
int idx[MAXN];
long long d[][MAXN];
void dp0(int u){
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
dp0(v);
if(d[][u]<=d[][v]+edge[i].w){
d[][u]=d[][u];
d[][u]=d[][v]+edge[i].w;
idx[u]=v;
}else if(d[][u]<d[][v]+edge[i].w){
d[][u]=d[][v]+edge[i].w;
}else if(d[][u]<d[][v]+edge[i].w){
d[][u]=d[][v]+edge[i].w;
}
}
}
void dp1(int u){
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(idx[u]==v) d[][v]=max(d[][u],d[][u])+edge[i].w;
else d[][v]=max(d[][u],d[][u])+edge[i].w;
dp1(v);
}
}
struct Que{
int que[MAXN],front,rear;
bool isEmpty(){
return front==rear;
}
int getFront(){
return que[front];
}
int getRear(){
return que[rear-];
}
void push(int a){
que[rear++]=a;
}
}mxq,mmq;
int main(){
memset(head,-,sizeof(head));
int n,m,a,b;
scanf("%d%d",&n,&m);
for(int i=; i<=n; ++i){
scanf("%d%d",&a,&b);
addEdge(a,i,b);
}
dp0();
dp1();
int res=;
for(int i=,j=; i<=n; ++i){
d[][i]=max(d[][i],d[][i]);
while(!mxq.isEmpty() && d[][mxq.getRear()]<d[][i]) --mxq.rear;
mxq.push(i);
while(!mmq.isEmpty() && d[][mmq.getRear()]>d[][i]) --mmq.rear;
mmq.push(i);
while(d[][mxq.getFront()]-d[][mmq.getFront()]>m){
if(mxq.getFront()<mmq.getFront()) j=mxq.getFront()+,++mxq.front;
else j=mmq.getFront()+,++mmq.front;
}
res=max(res,i-j+);
}
printf("%d",res);
return ;
}
POJ3162 Walking Race(树形DP+尺取法+单调队列)的更多相关文章
- 【POJ3162】Walking Race 树形dp+单调队列+双指针
题目大意:给定一棵 N 个节点的无根树,边有边权,现生成一个序列 d,d[i] 表示 i 号节点到树上其他节点距离的最大值.给定一个 m,求 d 序列中最大值和最小值之差不超过 m 的最长连续段的长度 ...
- POJ - 3162 Walking Race 树形dp 单调队列
POJ - 3162Walking Race 题目大意:有n个训练点,第i天就选择第i个训练点为起点跑到最远距离的点,然后连续的几天里如果最远距离的最大值和最小值的差距不超过m就可以作为观测区间,问这 ...
- [POJ3162]Walking Race(DP + 单调队列)
传送门 题意:一棵n个节点的树.wc爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要在这n个距离里取连续的若干天,使得这些天里最大距离和最小距离 ...
- 【题解】poj 3162 Walking Race 树形dp
题目描述 Walking RaceTime Limit: 10000MS Memory Limit: 131072KTotal Submissions: 4941 Accepted: 1252Case ...
- POJ 3162 Walking Race 树形DP+线段树
给出一棵树,编号为1~n,给出数m 漂亮mm连续n天锻炼身体,每天会以节点i为起点,走到离i最远距离的节点 走了n天之后,mm想到知道自己这n天的锻炼效果 于是mm把这n天每一天走的距离记录在一起,成 ...
- POJ 3162.Walking Race 树形dp 树的直径
Walking Race Time Limit: 10000MS Memory Limit: 131072K Total Submissions: 4123 Accepted: 1029 Ca ...
- 【BZOJ2282】[Sdoi2011]消防 树形DP+双指针法+单调队列
[BZOJ2282][Sdoi2011]消防 Description 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这 ...
- POJ 3162 Walking Race 树形dp 优先队列
http://poj.org/problem?id=3162 题意 : 一棵n个节点的树.wc爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要 ...
- HDU 4123 Bob’s Race 树形dp+单调队列
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 Time Limit: 5000/2000 MS (Java/Others) Memory L ...
随机推荐
- 一个PHP写的简单webservice服务端+客户端
首先是服务端,服务端有一个主要的class组成:apiServer.php <?php /** * apiServer.php * * webservice主类 * * @filename ap ...
- 压缩 javascript 和 css
www.iwangzheng.com 目前我们项目中的 CSS/JS 文件比较多, 由于RAILS 3.0 没有提供asset pipeline功能,所以这样会制约我们的访问速度. 例如: 目前,我 ...
- [ZJOI3527][Zjoi2014]力
[ZJOI3527][Zjoi2014]力 试题描述 给出n个数qi,给出Fj的定义如下: 令Ei=Fi/qi.试求Ei. 输入 包含一个整数n,接下来n行每行输入一个数,第i行表示qi. 输出 有n ...
- Phpstorm常用设置
Phpstorm更换主题和字体 1.File -- settings -- Editor -- Colors And Fonts: 2.在右侧窗口中选择Scheme name : 选择一个自己喜欢的主 ...
- PHPNG (next generation)
PHPNG (next generation) This page gives short information about development state of a new PHP branc ...
- 创建一个最简单的Linux随机启动服务
转自: http://xiaoxia.org/2011/11/15/create-a-simple-linux-daemon/
- HTML表单元素Emil和密码
<form action="" method="post" name="myform"><p>E-mail:< ...
- iOS和android游戏纹理优化和内存优化(cocos2d-x)(转载)
转自http://blog.csdn.net/langresser_king/article/details/8426708 (未完成) 1.2d游戏最占内存的无疑是图片资源. 2.cocos2d-x ...
- 【JAVA、C++】LeetCode 020 Valid Parentheses
Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the inpu ...
- PHP--TP框架----操作数据库
//操作数据库 //$attr = $m->select(); //查询所有数据 //$attr = $m->s ...