poj3162(树形dp+优先队列)
| Time Limit: 10000MS | Memory Limit: 131072K | |
| Total Submissions: 5409 | Accepted: 1371 | |
| 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 ≤ 106) and M (M < 109). 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
Hint
Explanation for the sample:
There are three check-points. Two paths of lengths 1 and 3 connect check-points 2 and 3 to check-point 1. The three paths along with wc walks are 1-3, 2-1-3 and 3-1-2. And their lengths are 3, 4 and 4. Therefore data from all three days can be used for analysis.
Source
1 2
2 4
2 2
1 6
1 5
6 1
6 1
7 2
7 3
10 1
11 4


#include<cstdio>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
struct{
int v,w,next;
}edge[2000010];//前向星存树
int head[1000010];
int cnt;
deque<ll> mx,mn;//双向队列求连续天数
struct{
ll lfst;//最长距离
ll lsnd;//次长距离
}dp[1000010];
ll ans[1000010];//存实际最长距离
void add(int u,int v,int w){//加边
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt++;
} void dfs1(int k,int fz){//(当前节点,父亲节点)
//printf("%d\n",k);
for(int i=head[k];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(v==fz)
continue;
dfs1(v,k); //先往下递归
ll a=dp[v].lfst+edge[i].w;
if(a>dp[k].lfst){//更新最长,次长距离
dp[k].lsnd=dp[k].lfst;
dp[k].lfst=a;
}
else if(a>dp[k].lsnd)
dp[k].lsnd=a;
}
}
void dfs2(int k,int fz,int w){//(儿子节点,根节点,儿子节点到根节点的距离)
//printf("wwww%d %d %d %d\n",k,fz,dp[fz].lfst,dp[fz].lsnd);
if(dp[k].lfst+w==dp[fz].lfst){//如果当前节点在其父亲节点的最长距离线路上
ll a=w+dp[fz].lsnd;//尝试走父亲节点的次长距离
if(a>dp[k].lfst){
dp[k].lsnd=dp[k].lfst;
dp[k].lfst=a;
}
else if(a>dp[k].lsnd)
dp[k].lsnd=a;
ans[k]=dp[k].lfst;
}
else{
ll a=w+dp[fz].lfst;//尝试走父亲节点的最长距离
if(a>dp[k].lfst){//比较并更新
dp[k].lsnd=dp[k].lfst;
dp[k].lfst=a;
}
else if(a>dp[k].lsnd)
dp[k].lsnd=a;
ans[k]=dp[k].lfst;//求出实际最长距离
}
for(int i=head[k];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(v==fz)
continue;
dfs2(v,k,edge[i].w);
}
}
void addmn(int k){//加入递增队列
while(mn.size()&&(ans[mn.back()]>ans[k])){//保持加入节点后队列的单调性
mn.pop_back();
}
mn.push_back(k);
}
void addmx(int k){//加入递减队列
while(mx.size()&&(ans[mx.back()]<ans[k])){
mx.pop_back();
}
mx.push_back(k);
}
int main(){
int n,m;
int v,w;
cnt=0;
scanf("%d%d",&n,&m);
fill(head,head+n+2,-1);//初始化
dp[0].lfst=dp[0].lsnd=0;
dp[1].lfst=dp[1].lsnd=0;
for(int i=2;i<=n;i++){
scanf("%d%d",&v,&w);
dp[i].lfst=dp[i].lsnd=0;//初始化
add(i,v,w);
add(v,i,w);
}
dfs1(1,0);
ans[1]=dp[1].lfst;//我是以1根,那么1的实际最长距离就等于它的最长距离
for(int i=head[1];i!=-1;i=edge[i].next){//往它的儿子节点遍历
dfs2(edge[i].v,1,edge[i].w);//(儿子节点,根节点,儿子节点到根节点的距离)
}
mx.clear();
mn.clear();
mx.push_back(1);//先放入第一天
mn.push_back(1);
int len=0;
int len1=1;
int lf=1;//左标记,表示以第几天开始来计算
for(int i=2;i<=n;i++){
addmx(i);//将该天加入到队列里
addmn(i);
len1++;//长度加1
while(lf<i&&len1&&abs(ans[mn.front()]-ans[mx.front()])>m){//如果绝对差大于m,那么开始天数要往右移
len1--;//当前绝对差大于m,我们要尝试右移开始天数来使得绝对差变小
if(mn.front()==lf)//如果当前的开始天数是最小的距离
mn.pop_front();
if(mx.front()==lf)//如果当前的开始天数是最大距离
mx.pop_front();
lf++;
}
len=max(len,len1);//更新答案
//printf("wwwwwww%d %lld %lld %d\n",i,mn.front(),mx.front(),lf);
}
printf("%d\n",len);
return 0;
}
poj3162(树形dp+优先队列)的更多相关文章
- poj3162 树形dp|树的直径 + 双单调队列|线段树,好题啊
题解链接:https://blog.csdn.net/shiqi_614/article/details/8105149 用树形dp是超时的,, /* 先求出每个点可以跑的最长距离dp[i][0|1] ...
- POJ 3162 Walking Race 树形dp 优先队列
http://poj.org/problem?id=3162 题意 : 一棵n个节点的树.wc爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要 ...
- Codeforces 1118 F2. Tree Cutting (Hard Version) 优先队列+树形dp
题目要求将树分为k个部分,并且每种颜色恰好在同一个部分内,问有多少种方案. 第一步显然我们需要知道哪些点一定是要在一个部分内的,也就是说要求每一个最小的将所有颜色i的点连通的子树. 这一步我们可以将所 ...
- poj3162(树形dp+线段树求最大最小值)
题目链接:https://vjudge.net/problem/POJ-3162 题意:给一棵树,求每个结点的树上最远距离,记为a[i],然后求最大区间[l,r]满足区间内的max(a[i])-min ...
- POJ3162 Walking Race(树形DP+尺取法+单调队列)
题目大概是给一棵n个结点边带权的树,记结点i到其他结点最远距离为d[i],问d数组构成的这个序列中满足其中最大值与最小值的差不超过m的连续子序列最长是多长. 各个结点到其他结点的最远距离可以用树形DP ...
- HDU 4123 Bob’s Race 树形dp+单调队列
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 Time Limit: 5000/2000 MS (Java/Others) Memory L ...
- 【树形DP】JSOI BZOJ4472 salesman
题目内容 vjudge链接 某售货员小T要到若干城镇去推销商品,由于该地区是交通不便的山区,任意两个城镇 之间都只有唯一的可能经过其它城镇的路线. 小T 可以准确地估计出在每个城镇停留的净收 益.这些 ...
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- COGS 2532. [HZOI 2016]树之美 树形dp
可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...
随机推荐
- radio为什么不能选择。急急急
<div class="control-group"> <label class="control-label" for="&quo ...
- shell 的多进程
例子 #!/bin/bash temp_fifo_file=$$.info #以当前进程号,为临时管道取名 mkfifo $temp_fifo_file #创建临时管道 exec <>$t ...
- MySQL优化查询 5.7版本
1. 变更参数 : query_cache_type 如果何配置查询缓存: query_cache_type 这个系统变量控制着查询缓存工能的开启的关闭.query_cache_type=0时表示关闭 ...
- docker 中安装 redis
使用以下命令在Docker Hub搜索Redis镜像docker search redis 使用以下命令拉取镜像,Redis的镜像docker pull redis:latest 使用以下命令查看,本 ...
- android使用smack实现简单登录功能
android端采用xmpp协议实现即时通讯,在最开始的登录功能就遇到了不少障碍.首先在官网(https://www.igniterealtime.org/projects/openfire/)下载o ...
- 【Linux】grep命令
grep 命令 在文件中搜索一个单词,命令会返回一个包含 “match_pattern” 的文本行: grep match_pattern file_name grep "match_pat ...
- 用html和css制作奥运五环
<html><head><meta charset="utf-8"> <style>.circle1,.circle2,.circl ...
- 基于Protostuff实现的Netty编解码器
在设计netty的编解码器过程中,有许多组件可以选择,这里由于咱对Protostuff比较熟悉,所以就用这个组件了.由于数据要在网络上传输,所以在发送方需要将类对象转换成二进制,接收方接收到数据后,需 ...
- centos7上搭建http服务器以及设置目录访问
参考文献:http://www.jb51.net/article/137596.htm,原文摘抄如下,并根据具体需要作了相应的修改. 步骤: 1. 安装httpd服务 sudo yum install ...
- GET 和 POST 请求的优缺点和误区
Get和Post在面试中一般都会问到,一般的区别:(1)post更安全(不会作为url的一部分,不会被缓存.保存在服务器日志.以及浏览器浏览记录中)(2)post发送的数据更大(get有url长度限制 ...