http://poj.org/problem?id=3162

题意:
一棵n个节点的树。有一个屌丝爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要在这n个距离里取连续的若干天,使得这些天里最大距离和最小距离的差小于M,问怎么取使得天数最多?

思路:
这道题目求最远距离和HDU 2196是一模一样的,这个不是很难。关键是要怎么处理得到的数据。

可以用单调队列做也可以用线段树来做,先介绍一下单调队列。

因为有最大值和最小值,所以我们需要两个单调队列,一个维护最大值,另一个维护最小值。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,ll> pll;
const int INF = 0x3f3f3f3f;
const int maxn=1e6+; int n, m;
int tot;
ll d[maxn][];
int path[maxn];
int head[*maxn];
int q_max[maxn];
int q_min[maxn]; struct node
{
int v,w,next;
}e[*maxn]; void addEdge(int u,int v,int w)
{
e[tot].v=v;
e[tot].w=w;
e[tot].next=head[u];
head[u]=tot++;
} void dfs1(int u,int fa)
{
d[u][]=d[u][]=;
path[u]=-;
for(int i=head[u];i!=-;i=e[i].next)
{
int v=e[i].v;
if(v==fa) continue;
dfs1(v,u);
if(d[u][]<d[v][]+e[i].w)
{
path[u]=v;
d[u][]=d[u][];
d[u][]=d[v][]+e[i].w;
}
else if(d[u][]<d[v][]+e[i].w)
d[u][]=d[v][]+e[i].w;
}
} void dfs2(int u,int fa)
{
for(int i=head[u];i!=-;i=e[i].next)
{
int v=e[i].v;
if(v==fa) continue;
if(path[u]==v) d[v][]=max(d[u][],d[u][])+e[i].w;
else d[v][]=max(d[u][],d[u][])+e[i].w;
dfs2(v,u);
}
} int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
tot=;
memset(head,-,sizeof(head));
for(int i=;i<=n;i++)
{
int v,w;
scanf("%d%d",&v,&w);
addEdge(i,v,w);
addEdge(v,i,w);
}
dfs1(,-);
dfs2(,-);
int ans=-;
int frt_max=,rear_max=;
int frt_min=,rear_min=;
for(int i=,j=;i<=n;i++)
{
d[i][]=max(d[i][],d[i][]);
while(frt_max<rear_max && d[q_max[rear_max-]][]<d[i][]) rear_max--;
q_max[rear_max++]=i;
while(frt_min<rear_min && d[q_min[rear_min-]][]>d[i][]) rear_min--;
q_min[rear_min++]=i; while(frt_max<rear_max && frt_min<rear_min && d[q_max[frt_max]][]-d[q_min[frt_min]][]>m)
{
if(q_max[frt_max]>q_min[frt_min]) {j=q_min[frt_min]+;frt_min++;}
else {j=q_max[frt_max]+;frt_max++;}
}
ans=max(ans,i-j+);
}
printf("%d\n",ans);
}
return ;
}

单调队列

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,ll> pll;
const int INF = 0x3f3f3f3f;
const int maxn=1e6+; int n, m;
int tot;
ll d[maxn][];
int path[maxn];
int head[*maxn]; int MAX[maxn<<];
int MIN[maxn<<];
int query_max,query_min; struct node
{
int v,w,next;
}e[*maxn]; void addEdge(int u,int v,int w)
{
e[tot].v=v;
e[tot].w=w;
e[tot].next=head[u];
head[u]=tot++;
} /**********************************************
dfs
**********************************************/ void dfs1(int u,int fa)
{
d[u][]=d[u][]=;
path[u]=-;
for(int i=head[u];i!=-;i=e[i].next)
{
int v=e[i].v;
if(v==fa) continue;
dfs1(v,u);
if(d[u][]<d[v][]+e[i].w)
{
path[u]=v;
d[u][]=d[u][];
d[u][]=d[v][]+e[i].w;
}
else if(d[u][]<d[v][]+e[i].w)
d[u][]=d[v][]+e[i].w;
}
} void dfs2(int u,int fa)
{
for(int i=head[u];i!=-;i=e[i].next)
{
int v=e[i].v;
if(v==fa) continue;
if(path[u]==v) d[v][]=max(d[u][],d[u][])+e[i].w;
else d[v][]=max(d[u][],d[u][])+e[i].w;
dfs2(v,u);
}
} /**********************************************
线段树
**********************************************/ void PushUp(int o)
{
MAX[o]=max(MAX[o<<],MAX[o<<|]);
MIN[o]=min(MIN[o<<],MIN[o<<|]);
} void build(int l, int r, int o)
{
if(l==r)
{
MAX[o]=MIN[o]=max(d[l][],d[l][]);
return;
}
int mid=(l+r)/;
build(l,mid,o<<);
build(mid+,r,o<<|);
PushUp(o);
} void query(int ql, int qr, int l, int r, int o)
{
if(ql<=l && qr>=r)
{
query_max=max(query_max,MAX[o]);
query_min=min(query_min,MIN[o]);
return;
}
int mid=(l+r)/;
if(ql<=mid) query(ql,qr,l,mid,o<<);
if(mid<qr) query(ql,qr,mid+,r,o<<|);
} int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
tot=;
memset(head,-,sizeof(head));
for(int i=;i<=n;i++)
{
int v,w;
scanf("%d%d",&v,&w);
addEdge(i,v,w);
addEdge(v,i,w);
}
dfs1(,-);
dfs2(,-);
build(,n,);
int ans=; int l=,r=;
while(r<=n)
{
query_max=; query_min=INF;
query(l,r,,n,);
if(query_max-query_min<=m) {ans=max(ans,r-l+);r++;}
while(query_max-query_min>m)
{
l++;
query_max=; query_min=INF;
query(l,r,,n,);
}
}
printf("%d\n",ans);
}
return ;
}

线段树

POJ 3162 Walking Race(树形dp+单调队列 or 线段树)的更多相关文章

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

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

  2. POJ 3162.Walking Race 树形dp 树的直径

    Walking Race Time Limit: 10000MS   Memory Limit: 131072K Total Submissions: 4123   Accepted: 1029 Ca ...

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

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

  4. 【POJ3162】Walking Race 树形dp+单调队列+双指针

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

  5. POJ 3162 Walking Race 树形DP+线段树

    给出一棵树,编号为1~n,给出数m 漂亮mm连续n天锻炼身体,每天会以节点i为起点,走到离i最远距离的节点 走了n天之后,mm想到知道自己这n天的锻炼效果 于是mm把这n天每一天走的距离记录在一起,成 ...

  6. POJ 3162 Walking Race 树形dp 优先队列

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

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

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

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

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

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

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

随机推荐

  1. 004-spring cloud gateway-网关请求处理过程

    一.网关请求处理过程 客户端向Spring Cloud Gateway发出请求.如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序.此处理程序运行通过特定于请求的过滤器链发送请求. ...

  2. 如何修改WordPress网站默认登录地址wp-admin

    使用过WordPress程序建网站的学员都知道,我们使用Wordpress建好的网站,它的网站登录后台就是“网站域名/wp-admin”.如下图: 为了网站安全,如何修改Wordpress网站默认登录 ...

  3. thinkpad X1 extreme 安装Ubuntu 18.04.2 LTS

    1.安装的时候需要禁用:nouveau.modeset=0 2.安装完成之后需要添加:acpi=off ,ro后面加上3,直接进入终端 3.启动之后:安装nvdia驱动 $ ubuntu-driver ...

  4. PAT 1021 Deepest Root[并查集、dfs][难]

    1021 Deepest Root (25)(25 分) A graph which is connected and acyclic can be considered a tree. The he ...

  5. AngularJS 模型

    ng-model 指令将HTML 控制器(input, select, textarea)的值 和 应用程序数据进行绑定. ng-model 指令 ng-model 指令可以将输入域的值与 Angul ...

  6. SQL中常见语句

    SQL中常见语句笔记: --替换字段中的回车符和换行符 ) ), '') --删除表命令 DROP TABLE [dbo].[MGoods_Test] --删除表中数据命令 DELETE FROM [ ...

  7. 用Python实现随机森林算法,深度学习

    用Python实现随机森林算法,深度学习 拥有高方差使得决策树(secision tress)在处理特定训练数据集时其结果显得相对脆弱.bagging(bootstrap aggregating 的缩 ...

  8. Jquery图片上传组件,支持多文件上传

    Jquery图片上传组件,支持多文件上传http://www.jq22.com/jquery-info230jQuery File Upload 是一个Jquery图片上传组件,支持多文件上传.取消. ...

  9. 简化document.createElement("div")动态生成层方法

    我们在WEB开发时,很多时候往往需要我们 JavaScript 来动态建立 html 元素,动态的设置相关的属性.比方说我们想要建立一個 div 层,则可以使用以下代码实现. 一.直接建立functi ...

  10. php检查是否是数字和字母

    /* 检查是否是数字和字母* php内置函数ctype_alnum检查字符串是否是数字和字母,或者两者混合* $string*/ public function is_numandlitter($st ...