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 ...
随机推荐
- js之作用域链到闭包
一.作用域 全局作用域和函数作用域(局部作用域). 一个变量的作用域就是源代码中定义这个变量的区域. 二.作用域链和闭包 全局变量只有一个(window,globel),全局环境下每一个函数都会形成一 ...
- SSH应用实战——安全防护(fail2ban)
ssh 安全配置 端口 ssh随机端口范围在 27000-30000,可以手动修改也要改在这个范围内,建议定时修改端口. 密码 登陆密码应包含大小写.数字.特殊字符等 10 位以上,建议定期修改密码. ...
- 利用window.name+iframe跨域获取接口数据
最近做了一个表单广告,需要从接口读取数据,做完发现谷歌火狐下正常,360兼容和IE浏览器无法获取数据,以下是鲜明的对比: 调试发现报错了: 然后开发把接口改成支持windowname,一开始 ...
- 【数论】 快速幂&&矩阵快速幂
首先复习快速幂 #include<bits/stdc++.h> using namespace std; long long power(long long a,long long b,l ...
- php上传文件,接口是java,go。
$uri = ‘https://www.xxx.com/api/xxxxx’; $ch = curl_init(); //加@符号curl就会把它当成是文件上传处理 $tmpName = $_FILE ...
- gitlab安装随记
gitlab安装 配置yum源 sudo vim /etc/yum.repos.d/gitlab-ce.repo 按照网上别人的例子,修改为清华的源 [gitlab-ce] name=Gitlab C ...
- Vue入门笔记(二)--基础部分之条件渲染
github地址:https://github.com/iTao9354/basicVue/tree/master/conditional%20rendering(demo01-03) 一.v-if ...
- C# Thread IsAlive 理解
IsAlive的功能就是判断当前线程是否处于活动状态. public class Program { public static void Main(string[] args) { try { Wr ...
- ClientDataSet使用locate或Filter定位到字段为空值的记录
场景,程序想检查是否存在某个字段的值是空的,如果存在,则不允许增加记录,否则允许增加记录. 解决这个问题,我一开始用了两种错误的方法 if not clientdataset.locate('AFie ...
- padding属性很有用
html代码中的text-align有时失效,特别是用bootstrap时,用padding-left:xx%,能够很好定位,而且只能够电脑和手机浏览器显示的统一.