【题解】poj 3162 Walking Race 树形dp
题目描述
Walking Race
Time Limit: 10000MS Memory Limit: 131072K
Total Submissions: 4941 Accepted: 1252
Case Time Limit: 3000MS
Description
flymouse’s sister wc is very capable at sports and her favorite event is walking race. Chasing after the championship in an important competition, she comes to a training center to attend a training course. The center has N check-points numbered 1 through N. Some pairs of check-points are directly connected by two-way paths. The check-points and the paths form exactly a tree-like structure. The course lasts N days. On the i-th day, wc picks check-point i as the starting point and chooses another check-point as the finishing point and walks along the only simple path between the two points for the day’s training. Her choice of finishing point will make it that the resulting path will be the longest among those of all possible choices.
After every day’s training, flymouse will do a physical examination from which data will obtained and analyzed to help wc’s future training be better instructed. In order to make the results reliable, flymouse is not using data all from N days for analysis. flymouse’s model for analysis requires data from a series of consecutive days during which the difference between the longest and the shortest distances wc walks cannot exceed a bound M. The longer the series is, the more accurate the results are. flymouse wants to know the number of days in such a longest series. Can you do the job for him?
Input
The input contains a single test case. The test case starts with a line containing the integers N (N ≤ 10^{6}) and M (M < \10^{9}). Then follow N − 1 lines, each containing two integers fi and di (i \= 1, 2, …, N − 1), meaning the check-points i + 1 and fi are connected by a path of length di.
Output
Output one line with only the desired number of days in the longest series.
Sample Input
3 2
1 1
1 3
Sample Output
3
题目大意
题目大概是给一棵n个结点边带权的树,记结点i到其他结点最远距离为d[i],问d数组构成的这个序列中满足其中最大值与最小值的差不超过m的连续子序列最长是多长。
思路
各个结点到其他结点的最远距离可以用树形DP解决,HDU2196
因为有最大值和最小值,需要两个单调队列,一个维护最大值qmax,另一个维护最小值qmin
具体操作看代码
代码
#include<cmath>
#include<deque>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register int
using namespace std;
inline int read(){
int x=0,w=1;
char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-48,ch=getchar();
return x*w;
}
const int MAXN=1e6+200;
struct edge {
int to,next,w;
} edges[MAXN*2];
int tot,dis[MAXN];
int head[MAXN];
void add_edge(int u,int v,int w) {
edges[tot].to=v;
edges[tot].w=w;
edges[tot].next = head[u];
head[u] = tot++;
}
int dist[MAXN][3]; //dist[i][0,1,2]分别为正向最大距离,正向次大距离,反向最大距离
int longest[MAXN];
int dfs1(int u,int fa) {
if(dist[u][0]>=0) return dist[u][0];
dist[u][0]=dist[u][1]=dist[u][2]=longest[u]=0;
for(re i=head[u];i!=-1;i=edges[i].next) {
int v=edges[i].to;
if(v==fa) continue;
if(dist[u][0]<dfs1(v,u)+edges[i].w) {
longest[u]=v;
dist[u][1]=max(dist[u][1],dist[u][0]);
dist[u][0]=dfs1(v,u)+edges[i].w;
}
else if(dist[u][1]<dfs1(v,u)+edges[i].w)
dist[u][1]=max(dist[u][1],dfs1(v,u)+edges[i].w);
}
return dist[u][0];
} void dfs2(int u,int fa) {
for(int i=head[u];i!=-1;i=edges[i].next) {
int v = edges[i].to;
if(v==fa)continue;
if(v==longest[u]) dist[v][2]=max(dist[u][2],dist[u][1])+edges[i].w;
else dist[v][2]=max(dist[u][2],dist[u][0])+edges[i].w;
dfs2(v,u);
}
} int finish(int n,int M){
if(n <= 0) return n;
if(M < 0) return 0;
deque<int> qmax,qmin; //qmax单调递减 qmin单调递增
deque<int> idmax,idmin; //id存节点编号(同样单调)
int ans=0;
int left=1,right=1;
while(right <= n){
//维护单调性
while(!qmax.empty() && dis[right] >= qmax.back()) qmax.pop_back(), idmax.pop_back();
qmax.push_back(dis[right]); idmax.push_back(right);
while(!qmin.empty() && dis[right] <= qmin.back()) qmin.pop_back(), idmin.pop_back();
qmin.push_back(dis[right]); idmin.push_back(right);
while(qmax.front()-qmin.front() > M && left<right){ //超出m就减少最大值/增大最小值(左指针右移)
left++;
while(idmax.front() < left) idmax.pop_front(), qmax.pop_front();
while(idmin.front() < left) idmin.pop_front(), qmin.pop_front();
}
ans = max(ans,right-left+1);
right++;
}
return ans;
}
int main() {
int n,m;
while(scanf("%d%d",&n,&m)==2&&n) {
tot=0;
memset(dist,-1,sizeof(dist));
memset(head,-1,sizeof(head));
memset(longest,-1,sizeof(longest));
for(int i=2; i<=n; i++) {
int v,w;
scanf("%d%d",&v,&w);
add_edge(i,v,w);
add_edge(v,i,w);
}
dfs1(1,-1);
dfs2(1,-1);
for(int i=1;i<=n;i++) dis[i]=max(dist[i][0],dist[i][2]);
printf("%d\n",finish(n,m));
}
return 0;
}
【题解】poj 3162 Walking Race 树形dp的更多相关文章
- POJ 3162.Walking Race 树形dp 树的直径
Walking Race Time Limit: 10000MS Memory Limit: 131072K Total Submissions: 4123 Accepted: 1029 Ca ...
- POJ - 3162 Walking Race 树形dp 单调队列
POJ - 3162Walking Race 题目大意:有n个训练点,第i天就选择第i个训练点为起点跑到最远距离的点,然后连续的几天里如果最远距离的最大值和最小值的差距不超过m就可以作为观测区间,问这 ...
- POJ 3162 Walking Race 树形DP+线段树
给出一棵树,编号为1~n,给出数m 漂亮mm连续n天锻炼身体,每天会以节点i为起点,走到离i最远距离的节点 走了n天之后,mm想到知道自己这n天的锻炼效果 于是mm把这n天每一天走的距离记录在一起,成 ...
- POJ 3162 Walking Race 树形dp 优先队列
http://poj.org/problem?id=3162 题意 : 一棵n个节点的树.wc爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要 ...
- POJ 3162 Walking Race(树形dp+单调队列 or 线段树)
http://poj.org/problem?id=3162 题意:一棵n个节点的树.有一个屌丝爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要 ...
- 【POJ3162】Walking Race 树形dp+单调队列+双指针
题目大意:给定一棵 N 个节点的无根树,边有边权,现生成一个序列 d,d[i] 表示 i 号节点到树上其他节点距离的最大值.给定一个 m,求 d 序列中最大值和最小值之差不超过 m 的最长连续段的长度 ...
- POJ 3162 Walking Race(树的直径+单调队列)
题目大意:对一棵树,求出从每个结点出发能到走的最长距离(每个结点最多只能经过一次),将这些距离按排成一个数组得到dis[1],dis[2],dis[3]……dis[n] ,在数列的dis中求一个最长的 ...
- POJ 3162 Walking Race (树的直径,单调队列)
题意:给定一棵带边权的n个节点的树,首先要求出每个点的最长路,然后写成序列d[1],d[2]...d[n],然后求满足 区间最大值-区间最小值<=k 的最大区间长度为多少? 思路: 分两步进行: ...
- poj 2324 Anniversary party(树形DP)
/*poj 2324 Anniversary party(树形DP) ---用dp[i][1]表示以i为根的子树节点i要去的最大欢乐值,用dp[i][0]表示以i为根节点的子树i不去时的最大欢乐值, ...
随机推荐
- liunx中文件夹不能删除怎么操作
1.运行rm -rf 文件名称 2.不能删除对应文件并且提示"rm: cannot remove './.user.ini': Operation not permitted" 操 ...
- Java前后端分离的认识
1.原由 在网上查了关于前后端分离的资料,有所粗浅认识.记录下来,方便以后使用.以下均是个人看法,仅做参考.如有错误请指教,共同进步. 2.为什么前后端分离? ①.一个后台,可以让多种前台系统使用.后 ...
- 【转】风控中的特征评价指标(二)——PSI
转自:https://zhuanlan.zhihu.com/p/79682292 风控业务背景 在风控中,稳定性压倒一切.原因在于,一套风控模型正式上线运行后往往需要很久(通常一年以上)才会被替换下线 ...
- java 运用Cipher加密再解密后会变乱码。解决方案!
同样的方法类用main调用加解密都正常,就是当用到业务就是加密后再解密变乱码. 后来发现同样的内容加密后的内容竟不相同. 经调试发现 encryptData.getBytes() 转为字节是的使用 C ...
- 通过CRM系统实现工作流程自动化
灵活运用CRM系统所拥有的自动化功能模块,是公司在快速发展和降低成本的关键保障.不管您的公司规模的大小,您企业的工作流程都必须遵照相同的流程反复操作.这种反复的工作是一个效率黑洞,长久以往会导致人力资 ...
- C++PRIMER第二章前半部分答案
C++PRIMER第二章前半部分答案 哈哈哈,为什么是前半部分呢,后半部分还在学习中,重新系统性的学习c++,共同进步嘛,不多说,跟我一起来看看吧,第三章开始才是新手收割的时候,慢慢来~~ 2.1&a ...
- Ansible_常用模块
一.Ansible常用模块 1.ansible常用模块command.shell.raw的区别: command模块不是调用的shell的指令,所以没有bash的环境变量 shell模块调用的/bin ...
- bond4以及vlan子接口配置
场景: 前提,交换机的配置由网络工程师配合! 1.跨交换机做bond,模式为LACP,linux双网卡做bond4,模式为4: 2.系统为centos7.0-123: 3.服务器仅有两张万兆网卡,为e ...
- 把采集到的数据发送到一个Google Docs或者Google Form上 这个网站提供了参考和例子
把采集到的数据发送到一个Google Docs或者Google Form上这个网站提供了参考和例子 http://www.instructables.com/id/Post-to-Google-Doc ...
- Linux基础命令学习记录(一)
使用频繁的Linux命令 一.文件和目录 1.cd命令 cd / 进入根目录 cd .. 返回上一级目录 cd ../.. 返回上两级目录 cd 进入个人的主目录 cd ~ 进入个人的主目录 cd - ...