题目大意:给定一棵 N 个节点的无根树,边有边权,现生成一个序列 d,d[i] 表示 i 号节点到树上其他节点距离的最大值。给定一个 m,求 d 序列中最大值和最小值之差不超过 m 的最长连续段的长度是多少。

题解:d[i] 直接两次 dfs 即可,考虑如何求出最长连续段。可以发现若当前 [l,r] 合法,则 [l+1,r] 一定也合法,这意味着随着 l 的左移,r 不可能向右移动,符合双指针的思想。在双指针的基础之上维护两个单调队列,用来记录区间 [l,r] 的最大值和最小值,当不符合条件时,统计答案并将左端点右移。

代码如下

#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=1e6+10; int n,m,ans,dp[maxn][3];
int qmin[maxn],l1,r1,qmax[maxn],l2,r2;
struct node{
int nxt,to,w;
node(int a=0,int b=0,int c=0):nxt(a),to(b),w(c){}
}e[maxn<<1];
int tot=1,head[maxn];
inline void add_edge(int from,int to,int w){
e[++tot]=node(head[from],to,w),head[from]=tot;
} void dfs1(int u,int fa){
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to,w=e[i].w;
if(v==fa)continue;
dfs1(v,u);
if(dp[u][0]<dp[v][0]+w){
dp[u][1]=dp[u][0];
dp[u][0]=dp[v][0]+w;
}else{
dp[u][1]=max(dp[u][1],dp[v][0]+w);
}
}
}
void dfs2(int u,int fa){
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to,w=e[i].w;
if(v==fa)continue;
if(dp[v][0]+w==dp[u][0])dp[v][2]=max(dp[u][1]+w,dp[u][2]+w);
else dp[v][2]=max(dp[u][0]+w,dp[u][2]+w);
dfs2(v,u);
}
} void read_and_parse(){
scanf("%d%d",&n,&m);
for(int i=2;i<=n;i++){
int to,w;scanf("%d%d",&to,&w);
add_edge(i,to,w),add_edge(to,i,w);
}
}
void solve(){
dfs1(1,0),dfs2(1,0);
l1=l2=1,r1=r2=0;
int i,j;
for(i=1,j=1;j<=n;j++){
dp[j][0]=max(dp[j][0],dp[j][2]);
while(l1<=r1&&dp[qmin[r1]][0]>=dp[j][0])--r1;
while(l2<=r2&&dp[qmax[r2]][0]<=dp[j][0])--r2;
qmin[++r1]=j,qmax[++r2]=j;
if(dp[qmax[l2]][0]-dp[qmin[l1]][0]>m){
ans=max(ans,j-i);
i=min(qmax[l2],qmin[l1])+1;
while(l1<=r1&&qmin[l1]<i)++l1;
while(l2<=r2&&qmax[l2]<i)++l2;
}
}
ans=max(ans,j-i);
printf("%d\n",ans);
}
int main(){
read_and_parse();
solve();
return 0;
}

【POJ3162】Walking Race 树形dp+单调队列+双指针的更多相关文章

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

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

  2. [POJ3162]Walking Race(DP + 单调队列)

    传送门 题意:一棵n个节点的树.wc爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要在这n个距离里取连续的若干天,使得这些天里最大距离和最小距离 ...

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

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

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

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

  5. POJ 3162 Walking Race(树形dp+单调队列 or 线段树)

    http://poj.org/problem?id=3162 题意:一棵n个节点的树.有一个屌丝爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要 ...

  6. 【题解】poj 3162 Walking Race 树形dp

    题目描述 Walking RaceTime Limit: 10000MS Memory Limit: 131072KTotal Submissions: 4941 Accepted: 1252Case ...

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

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

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

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

  9. bzoj2500幸福的道路 树形dp+单调队列

    2500: 幸福的道路 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 434  Solved: 170[Submit][Status][Discuss ...

随机推荐

  1. flask包request获取参数

    原博文:https://www.cnblogs.com/wangjikun/p/6935592.html request.method #获取请求方法request.form #获取post请求所有参 ...

  2. 阶段3 2.Spring_05.基于XML的IOC的案例1_1 基于XML的IOC的案例-案例准备

    导坐标 创建数据库表 create table account( id int primary key auto_increment, name varchar(40), money float )c ...

  3. 报错:Original error: Could not proxy command to remote server. Original error: Error: read ECONNRESET

    问题:Appium的android真机启动手机时,会遇到以下问题: An unknown server-side error occurred while processing the command ...

  4. 想使用 MongoDB ,你应该了解这8个方面!

    想使用 MongoDB ,你应该了解这8个方面! 应用性能高低依赖于数据库性能,MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写,旨在为 WEB 应用提供可扩展的高性能数据存储解 ...

  5. JMeter强大的性能测试工具

    JMeter强大的性能测试工具,可模拟服务器负载,进行性能测试 配合badboy采集请求数据.

  6. Tomcat启动报错:“通配符的匹配很全面, 但无法找到元素 'tx:annotation-driven' 的声明“

    从报错信息就可以明显察觉到是xml配置文件出现的问题 <?xml version="1.0" encoding="UTF-8"?> <bean ...

  7. 【转载】ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql'

    转载出处 在网上下载了一个免安装包的MySQL,准备自己create database jhp_test,使用的时候出现报错,如下: ERROR (): Access denied for user ...

  8. 病毒分析(三)-利用Process Monitor对熊猫烧香病毒进行行为分析

    前两次随笔我介绍了手动查杀病毒的步骤,然而仅通过手动查杀根本无法仔细了解病毒样本的行为,这次我们结合Process Monitor进行动态的行为分析. Process Monitor Process ...

  9. linux建立ftp用户

    #!/bin/bash sleep 1 mkdir -p /ceshi/ userdel ceshi useradd -d /ceshi -s /sbin/nologin ceshi echo mim ...

  10. C++ day01 预备知识、C++综述、教材、推荐阅读。

    C++ day01: 1.预备知识? 1)什么是编程 编程,即编订程序. 程序 = 数据 + 算法(蛋糕 = 糖.鸡蛋.奶油 + 打鸡蛋.加糖.烤) 2)编程语言 最初的编程是用二进制代码(即“机器码 ...