2500: 幸福的道路

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 434  Solved: 170
[Submit][Status][Discuss]

Description

 
小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光.
他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图.
他们不愿枯燥的每天从同一个地方开始他们的锻炼,所以他们准备给起点标号后顺序地从每个起点开始(第一天从起点一开始,第二天从起点二开始……). 而且他们给每条道路定上一个幸福的值.很显然他们每次出发都想走幸福值和最长的路线(即从起点到树上的某一点路径中最长的一条).
他们不愿再经历之前的大起大落,所以决定连续几天的幸福值波动不能超过M(即一段连续的区间并且区间的最大值最小值之差不超过M).他们想知道要是这样的话他们最多能连续锻炼多少天(hint:不一定从第一天一直开始连续锻炼)?
现在,他们把这个艰巨的任务交给你了!

Input

第一行包含两个整数N, M(M<=10^9).
第二至第N行,每行两个数字Fi , Di, 第i行表示第i个节点的父亲是Fi,且道路的幸福值是Di.

Output

最长的连续锻炼天数

Sample Input

3 2
1 1
1 3

Sample Output

3
数据范围:
50%的数据N<=1000
80%的数据N<=100 000
100%的数据N<=1000 000

这其实是两个题强行合在一起啊。。
首先是对于每个节点求它在树上的最长路,可以树形dp 2次,一次从儿子转移一次从父亲转移
求最长连续区间的话维护两个单调队列max min就好

 #include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define N 1000005
#define ll long long
using namespace std;
int n,m,tot,w[N],hd[N],ans=;
ll f[N],g[N],a[N];int mx[N],mn[N];
struct edge{int v,w,next;}e[N<<];
char gc(){
static char s[],*p1,*p2;
if(p1==p2)p2=(p1=s)+fread(s,,,stdin);
if(p1==p2)return EOF;
return *p1++;
}
int read(){
int x=;char ch=gc();
while(ch>''||ch<'')ch=gc();
while(ch<=''&&ch>='')x=x*+ch-'',ch=gc();
return x;
}
void adde(int u,int v,int w){
e[++tot].v=v;
e[tot].next=hd[u];
e[tot].w=w;
hd[u]=tot;
}
void dfs1(int u,int fa){
for(int i=hd[u];i;i=e[i].next){
int v=e[i].v;
if(v==fa)continue;
dfs1(v,u);
f[u]=max(f[u],f[v]+e[i].w);
}
}
void dfs2(int u,int fa){
ll mx1=,mx2=;
for(int i=hd[u];i;i=e[i].next){
int v=e[i].v;if(v==fa)continue;
if(f[v]+e[i].w>mx1)mx2=mx1,mx1=f[v]+e[i].w;
else if(f[v]+e[i].w>mx2)mx2=f[v]+e[i].w;
g[v]=g[u]+e[i].w;
}
for(int i=hd[u];i;i=e[i].next){
int v=e[i].v;if(v==fa)continue;
if(f[v]+e[i].w==mx1)g[v]=max(g[v],mx2+e[i].w);
else if(mx1+e[i].w>g[v])g[v]=mx1+e[i].w;
dfs2(v,u);
}
}
void solve(){
for(register int i=;i<=n;i++)a[i]=max(g[i],f[i]);
int l1=,l2=,r2=,r1=,t=;
for(register int i=;i<=n;i++){
while(l1<=r1&&a[i]>=a[mx[r1]])r1--;
while(l2<=r2&&a[i]<=a[mn[r2]])r2--;
mx[++r1]=i;mn[++r2]=i;
while(a[mx[l1]]-a[mn[l2]]>m){
if(mx[l1]<=mn[l2])t=mx[l1]+,l1++;
else t=mn[l2]+,l2++;
}
ans=max(ans,i-t+);
}
}
int main(){
n=read();m=read();
for(register int i=;i<=n;i++){
int v=read(),w=read();
adde(i,v,w);adde(v,i,w);
}dfs1(,);dfs2(,);
solve();printf("%d",ans);
return ;
}

bzoj2500幸福的道路 树形dp+单调队列的更多相关文章

  1. (noip模拟二十一)【BZOJ2500】幸福的道路-树形DP+单调队列

    Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. ...

  2. 【bzoj2500】幸福的道路 树形dp+单调队列

    Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. ...

  3. [BZOJ 2500]幸福的道路 树形dp+单调队列+二分答案

    考试的时候打了个树链剖分,而且还审错题了,以为是每天找所有点的最长路,原来是每天起点的树上最长路径再搞事情.. 先用dfs处理出来每个节点以他为根的子树的最长链和次长链.(后面会用到) 然后用类似dp ...

  4. bzoj2500: 幸福的道路(树形dp+单调队列)

    好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...

  5. 【bzoj2500】幸福的道路 树形dp+倍增RMQ+二分

    原文地址:http://www.cnblogs.com/GXZlegend/p/6825389.html 题目描述 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一 ...

  6. 【BZOJ2500】幸福的道路 树形DP+RMQ+双指针法

    [BZOJ2500]幸福的道路 Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的 ...

  7. Codeforces 980F Cactus to Tree 仙人掌 Tarjan 树形dp 单调队列

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF980F.html 题目传送门 - CF980F 题意 给定一个 $n$ 个节点 $m$ 条长为 $1$ 的边 ...

  8. HDU 4123 Bob’s Race 树形dp+单调队列

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 Time Limit: 5000/2000 MS (Java/Others) Memory L ...

  9. POJ - 3162 Walking Race 树形dp 单调队列

    POJ - 3162Walking Race 题目大意:有n个训练点,第i天就选择第i个训练点为起点跑到最远距离的点,然后连续的几天里如果最远距离的最大值和最小值的差距不超过m就可以作为观测区间,问这 ...

随机推荐

  1. equalsignorecase 和equals的区别

    equals方法来自于Object类equalsIgnoreCase方法来自String类equals对象参数是Object 用于比较两个对象是否相等equals在Object类中方法默然比较对象内存 ...

  2. 自己写编程语言-m语言

    一直对技术有很强的兴趣,终于,决定要写自己的语言(m语言).那就先从最简单的开始:解释执行器. 一套完整的语言包含的肯定不止解释执行器了,还要有编译器和IDE,也就还要有语法高亮.智能提示等,不过还没 ...

  3. slf4j 与 log4j2 实战讲解与日志分割

    这两天搭建项目的时候用到log4j2在这里把自己的问题与了解拿出来与大家分享一下. 1.为什我要用 因为,使用slf4j可以很好的保证我们的日志系统具有良好的兼容性,兼容当前常见几种日志系统,而使用l ...

  4. 看到一个对CAP简单的解释

    一个分布式系统里面,节点组成的网络本来应该是连通的.然而可能因为一些故障,使得有些节点之间不连通了,整个网络就分成了几块区域.数据就散布在了这些不连通的区域中.这就叫分区.当你一个数据项只在一个节点中 ...

  5. Python内置函数(16)——ord

    英文文档: ord(c) Given a string representing one Unicode character, return an integer representing the U ...

  6. WPF 自定义RadioButton样式

    一.RadioButton基本样式 RadioButton基本样式包含两种状态,这里也是使用两张图片来代替两种状态,当然你也可以通过IconFont或Path来替换这两种状态. 效果如下: 样式代码如 ...

  7. Dijkstra的双栈算术表达式求值算法

    这次来复习一下Dijkstra的双栈算术表达式求值算法,其实这就是一个计算器的实现,但是这里用到了不一样的算法,同时复习了栈. 主体思想就是将每次输入的字符和数字分别存储在两个栈中.每遇到一个单次结束 ...

  8. jsp连接书库DatabaseUtil类

    public class DatabaseUtil { private static String driver = ConfigManager.getProperties("driver& ...

  9. 归档(NSKeyedArchiver)的使用

    归档的使用,是归于使用保存数据,但是一些简单的数据,如数组,字典等基本的数据类型,往往不使用在归档中,归档和plist以及UserDefaults最大的区别就在于,前者可以存放自定义的数据类型,而后两 ...

  10. Python面向对象进阶示例--自定义数据类型

    需求: 基于授权定制自己的列表类型,要求定制的自己的__init__方法, 定制自己的append:只能向列表加入字符串类型的值 定制显示列表中间那个值的属性(提示:property) 其余方法都使用 ...