POJ - 3162Walking Race

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

  一开始楞是没看懂题意,最讨厌这种四级题,这是在刁难我英语小能手(能用翻译的就不自己动手)。而且这题感觉单调队列那里的处理更难一点,不过还是来说一说怎么树形dp取得最远距离,先画个简简单单丑丑的图

  我们直接从1作为根节点开始dfs的话,可以处理1的最远距离,并且可以得出到其它节点在其子树中的最短距离,然后怎么得到其他节点的最远距离呢?我们还是从1开始,2的最短距离无非就是1和2连接这一条边再加上除这条外的最长分支也就是1和4这条边,而3的话1和3连接的这条边是在1和4这条路径上的,所以对3来说最远距离就是1的除1和4这条外其他最长分支加上1和3连接的这条边与3和4连接的这条边中的最大值,所以我们可以更新一个每个节点的最大距离以及第二远距离还有最远距离来自哪个子节点的方向。

  这样的话先一遍dfs得出作为根节点的情况,还有其他节点到子树的情况,然后第二边dfs再由根节点去传入数据更新其他节点的最大值,也就判断子节点是否是最远距离方向的,是的话传入第二远距离,否则传入最远距离。

  然后就是取区间那里了,首先尺取思想,但需要一个单调递减队列维护区间最大值(最大值在队列首部),然后还需要一个单调递增队列维护区间最小值(最小值在队列首部),然后区间往右的同时,更新左端,详情见代码。

 #include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int N=;
struct Side{
int v,ne,len;
}S[*N];
int sn,n,m,head[N],dis1[N],dis2[N],path[N];
void add(int u,int v,int c)
{
S[sn].v=v;
S[sn].len=c;
S[sn].ne=head[u];
head[u]=sn++;
}
void updata(int u,int v,int dis)//更新距离
{
if(dis>dis1[u])//更新最大距离的来源点
path[u]=v;
dis2[u]=max(dis2[u],min(dis1[u],dis));
dis1[u]=max(dis1[u],dis);
}
void dfs1(int u,int f)
{
for(int i=head[u];i!=-;i=S[i].ne)
{
int v=S[i].v;
if(v!=f)
{
dfs1(v,u);//先搜索子节点
updata(u,v,dis1[v]+S[i].len);//更新
}
}
}
void dfs2(int u,int f,int len)
{
updata(u,f,len);//由父节点传入的距离更新距离
for(int i=head[u];i!=-;i=S[i].ne)
{
int v=S[i].v;
if(v!=f)
{
if(v==path[u])
dfs2(v,u,dis2[u]+S[i].len);
else
dfs2(v,u,dis1[u]+S[i].len);
}
}
}
int main()
{
int f,d;
while(~scanf("%d%d",&n,&m))
{
for(int i=;i<=n;i++)
{
head[i]=-;
dis1[i]=dis2[i]=;
}
sn=;
for(int i=;i<n;i++)
{
scanf("%d%d",&f,&d);
add(i+,f,d);
add(f,i+,d);
}
dfs1(,);
dfs2(,,);
deque<int> qx,qd;//qx单调递增队列,qd单调递减队列
int ans=; //注意是双向队列,单向没有back()
for(int i=,j=;i<=n;i++)//j是左端,i是右端
{
//维护单调性
while(qd.size()&&dis1[qd.back()]<dis1[i])
qd.pop_back();
while(qx.size()&&dis1[qx.back()]>dis1[i])
qx.pop_back();
qd.push_back(i);
qx.push_back(i);
while(qd.size()&&qx.size()&&dis1[qd.front()]-dis1[qx.front()]>m)
{
//当最大值减最小值大于m时这时左端的位置就需要调整了
//左端肯定是要调整到最大值和最小值中较近的位置的前面
if(qd.front()<qx.front())
{
j=qd.front();
qd.pop_front();
}
else
{
j=qx.front();
qx.pop_front();
}
//把区间外的数全部弹出
while(qd.size()&&qd.front()<=j)
qd.pop_front();
while(qx.size()&&qd.front()<=j)
qx.pop_front();
}
ans=max(ans,i-j);//更新区间长度
}
printf("%d\n",ans);
}
return ;
}

简简单单的低调

  连做了几题树形dp,不怎么说得出,不过感觉还是有点心得的。核心的思想还是在于它的一棵数的结构,我们可以把某个节点假设为根节点再由它的情况去推导出整棵树的情况。而且精华部分也正如dp,搞清楚dp什么,然后是状态转移的过程。想练好它,无疑就两个方法,做题,思考。

POJ - 3162 Walking Race 树形dp 单调队列的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. pyton 类(4) 静态方法

    class Cat(): tag = ' 猫科动物 ' def __init__(self, name): self.name = name @staticmethod def breah(): pr ...

  2. py2和py3之间的不同

    1.print函数 很琐碎,而 print 语法的变化可能是最广为人知的了,但是仍值得一提的是: Python 2 的 print 声明已经被 print() 函数取代了,这意味着我们必须包装我们想打 ...

  3. poj 3320 复习一下尺取法

    尺取法(two point)的思想不难,简单来说就是以下三步: 1.对r point在满足题意的情况下不断向右延伸 2.对l point前移一步 3.  回到1 two point 对连续区间的问题求 ...

  4. GET方法和POST方法的区别,Get方法到底可传递的字符串的最大长度是多少?

    GET方法和POST方法的区别,Get方法到底可传递的字符串的最大长度是多少?曾经人介绍,如果使用GET方式传输参数,URL的最大长度是256个字节,对此深信不疑. 但是最近看到一些超长的url,能够 ...

  5. IIS--解决64位系统IIS网站发布出现未能加载文件或程序集“...”或它的某一个依赖项。试图加载

    解决64位系统IIS网站发布出现未能加载文件或程序集“...”或它的某一个依赖项.试图加载 ASP.NET MVC 项目发布的在本地IIS后,启动网站出现未能加载文件或程序集“…”或它的某一个依赖项. ...

  6. 【web性能优化】当用户输入网址后发生了什么?

    简单叙述 这个过程可以大致分为两个部分:网络通信和页面渲染. 一.网络通信 互联网内各网络设备间的通信都遵循TCP/IP协议,利用TCP/IP协议族进行网络通信时,会通过分层顺序与对方进行通信.分层由 ...

  7. LeetCode 腾讯精选50题--数组中的第K个最大元素

    好吧,不得不承认,书上看到的始终不是自己的,只有亲身时间过才会明白该怎么操作. 找数组中第K个最大元素,简而言之就是先排序,不论使用哪种算法,都需要先排序,确认位置,由于数组可以通过下标直接访问,所以 ...

  8. Dreamweaver CS6 破解安装

    安装 双击Dreamweaver.dmg文件,然后Command+N,新建一个Finder,接着将Adobe Dreamweaver CS6拖到新建Finder的应用程序中.   在Finder中应用 ...

  9. 修改Vue中的 v-html 内的元素无效问题

    其原因就是在 style 样式中没有去处scoped 因为 v-html 会把内容当成子组件,而scoped 会在本身的组件中起作用

  10. python转化13位时间戳

    # -*- coding: utf-8 -*- def get_time_stamp13(datetime_obj): import datetime, time # 生成13时间戳 eg:15578 ...