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 ...
随机推荐
- arcgis raster clip and mask difference 栅格 提取 clip 和 mask 方法的区别
建议使用 数据管理工具下的此工具进行操作: 在选择参数时,注意做如下选择,可以保证栅格不会轻微错开: 也就是勾选第一个,而不勾选第二个 看看效果,使用mask得到的裁剪结果,注意有错开现象: 使用cl ...
- c++ 线程间通信方式
一:两个进程间的两个线程通信,相当于进程间通信 二:一个进程中的两个线程间通信 通信方式: 1.互斥锁 mutex; lock_guard (在构造函数里加锁,在析构函数里解锁) unique_loc ...
- (23)socket多进程并发
# 对于服务器自己本身,一个程序只能绑定一个端口 # 同一个端口可以多个客户端来连接, # 只要server_ip+ server_port +client_ip + cilent_port 不一样, ...
- Spring Cloud ----> 几个组件的总结
Spring Cloud Eureka 多个服务,对应多个Eureka Client 只有一个Eureka Server ,充当注册中心的角色每个Eureka Client 有ip 地址和端口号,它们 ...
- 移动app的体验性测试
最近用户体验被提的次数较多,大家可能会遇到这种情况,客户“你们软件功能没问题了,但就是感觉不好用,能不能优化一下,做的高大上些”,作为一个有经验的测试工程师这个时候你就应该知道问题在于用户体验了 关于 ...
- LeetCode--031--下一个排列(java)*
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列. 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列). 必须原地修改,只允许使用额外常数空间. ...
- 深入理解Plasma(四)Plasma Cash
这一系列文章将围绕以太坊的二层扩容框架 Plasma,介绍其基本运行原理,具体操作细节,安全性讨论以及未来研究方向等.本篇文章主要介绍在 Plasma 框架下的项目 Plasma Cash. 在上一篇 ...
- 1GB pages can only be allocated at boot time using hugepages= and not freed afterwards
2018-6-27 9:12:38 https://stackoverflow.com/questions/26385554/error-setting-nr-hugepages-via-sysfs ...
- Java JDK 获取MongoDB中的所有账户
记录我在Stack Overflow中的回答: https://stackoverflow.com/questions/31518107/mongodb-java-list-all-database- ...
- linux-centos系统下安装python3.5.4步骤
查看当前python版本:python -V 查看Python可执行文件位置:which python [root@localhost bin]# which python/usr/bin/pytho ...