POJ3162-Walking Race

2024-01-08 14:08
文章标签 race walking poj3162

本文主要是介绍POJ3162-Walking Race,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目:

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 Ndays. 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 fiare 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.

 

题目大意:

给定一棵树,对于这棵树从1到n的每一个结点,在树上都能找到一个距离它最远的结点,记录从1到n这n个结点的最长距离dis[i],要求一段区间,满足这段区间内dis的最大值与最小值之差小于等于m,求这一段连续区间最长能是多长。

 

解题思路:

先用树形DP求出每个点能到达的最远距离,然后再使用两个单调队列,一个维护最大值,一个维护最小值,这样就能求出最长区间了。

树形DP求最远距离:两次dfs,一次由叶子转移到树根,一次由树根转移到叶子。

第一次dfs求出该结点到它的子节点的最远距离。

第二次dfs求出从该结点向上走能到达的最远距离。

对于第二次dfs的向上走,我们有可能在往上走k个结点之后,就又开始往下走,那往上走是只有唯一一条路径的,那么这段路径能求出来,而往下走的最远距离,就能用到我们第一次dfs求得的该结点的最远距离了。十分巧妙

#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#include<queue>using namespace std;
const long long inf = 0x3f3f3f3f3f3f3f3f;
const int maxn = 1000005;int n, m, k;struct Edge
{int to,nxt;long long w;
} edges[maxn<<2];
int head[maxn<<2];
int tot;void addEdge(int u, int v, long long w)
{edges[tot] = Edge{v,head[u],w};head[u] = tot++;
}long long dp1[maxn]; //从该结点往下走能走的最远距离
long long dp2[maxn]; //从该节点往上走能走的最远距离void dfs1(int u, int fa)
{for(int i = head[u]; ~i; i = edges[i].nxt){int to = edges[i].to;long long w = edges[i].w;if(to == fa)continue;dfs1(to,u);dp1[u] = max(dp1[u],dp1[to]+w);}
}void dfs2(int u, int fa, int ancestor, long long d) //当前结点,当前结点父亲,当前结点爷爷,父亲到当前点距离
{dp2[u] = dp2[fa];for(int i = head[fa]; ~i; i = edges[i].nxt){int to = edges[i].to;long long w = edges[i].w;if(to == u||to==ancestor)continue;dp2[u] = max(dp2[u],w+dp1[to]);}dp2[u]+=d;for(int i = head[u]; ~i; i = edges[i].nxt){int v = edges[i].to;long long w = edges[i].w;if(v == fa) continue;dfs2(v,u,fa,w);}
}long long qb[maxn];
long long qs[maxn];int main()
{int n;long long m;scanf("%d%lld", &n, &m);int u, v;long long w;memset(head,-1,sizeof(head));tot = 1;for(u = 2; u <= n; u++){scanf("%d%lld", &v, &w);addEdge(u,v,w);addEdge(v,u,w);}dfs1(1,0);dfs2(1,0,-1,0);for(int i = 1; i <= n; i++){dp1[i] = max(dp1[i],dp2[i]);
//        cout << dp1[i]<<" ";}
//    cout <<endl;int headb = 1,tailb = 0, heads = 1, tails = 0;int ans = 0;int minn = 0;for(int i = 1; i <= n; i++){while(tailb>=headb&&dp1[i]>dp1[qb[tailb]])tailb--;qb[++tailb] = i;while(tails>=heads&&dp1[i]<dp1[qs[tails]])tails--;qs[++tails] = i;while(dp1[qb[headb]]-dp1[qs[heads]]>m){minn = min(qb[headb],qs[heads]);if(minn == qb[headb])headb++;if(minn == qs[heads])heads++;}ans = max(ans,i-minn);}printf("%d\n", ans);return 0;
}7 4
1 8
1 4
2 2
2 3
3 6
3 3

 

 

 

 

这篇关于POJ3162-Walking Race的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/583707

相关文章

Codeforces Round #328 (Div. 2)C. The Big Race(数学gcd lcm)

题目连接 题意:比赛时 ,居然理解错题意= =,以为两个人的速度是一样的,然后有个人的只会有一步是w米,另一个人只有一步是b米。。。。 就是一个人每一步是w,一个人每一步是b,终点后是深渊,然后长度是在1–t随机选择一个d作为赛道长度,问不能区分二人胜负的可能。 思路:就是求d%w==d%b = = #include<bits/stdc++.h>using namespace std;

Race Condition竞争条件

Race Condition Question – why was there no race condition in the first solution (where at most N – 1) buffers can be filled?Processes P0 and P1 are creating child processes using the fork() system

[js高手之路] es6系列教程 - promise常见用法详解(resolve,reject,catch,then,all,race)

关于promise我在之前的文章已经应用过好几次,如[js高手之路]Node.js jade express mongodb mongoose promise实现todolist,本文就来讲解下promise的常见用法. 为什么会有promise,他的作用是什么? promise主要是为了解决js中多个异步回调难以维护和控制的问题. 什么是promise? 从图中,我们可以看出,Pro

【C语言】解决C语言报错:Race Condition

文章目录 简介什么是Race ConditionRace Condition的常见原因如何检测和调试Race Condition解决Race Condition的最佳实践详细实例解析示例1:缺乏适当的同步机制示例2:错误使用条件变量 进一步阅读和参考资料总结 简介 Race Condition(竞争条件)是C语言中常见且复杂的并发编程错误之一。它通常在多个线程或进程并

Light OJ 1236 Race 第二类斯特林数

第二类斯特林数 n 匹马 分成1 2 3... n组 每一组就是相同排名 没有先后 然后组与组之间是有顺序的 在乘以组数的阶乘 #include <cstdio>#include <cstring>using namespace std;int dp[1010][1010];int a[1010];int main(){a[0] = 1;dp[0][0] = 1;for(int

uva 825 Walking on the Safe Side(动态规划:记忆化搜索)

题目的输入太蛋疼了... 题目本身倒是不难 代码如下: #include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAXN 1010using namespace std;char str[MAXN];int a[MAXN][MAXN], dp[MAXN][MAXN];i

LightOJ 1038 - Race to 1 Again(dp)

题目链接:LightOJ 1038 - Race to 1 Again 代码 #include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;const int maxn = 1e5;double dp[maxn + 5];vector<int> G[maxn +

UVA 11762 - Race to 1(概率)

UVA 11762 - Race to 1 题意:给定一个n,每次随即选择一个n以内的质数,如果不是质因子,就保持不变,如果是的话,就把n除掉该因子,问n变成1的次数的期望值 思路:tot为总的质数,cnt为质因子个数,那么f(n)=(1−cnt/tot)∗f(n)+∑f(n/prime)∗(1/tot),然后利用记忆化搜索去做即可 代码: #include <stdio.h

UVA 10913 - Walking on a Grid (记忆化搜索)

题目链接~~> 做题感悟:开始不用标记数组把 dp 数组初始化一下用于标记但是这样因为初始化的原因就超时了,改为标记数组才过。 解题思路:记忆化搜索                 这题很明显,如果用递推的方法的话必定不好写,因为在一行里可以向左做可以向右走,这样就导致不好递推,如果用记忆化方法的话就很好写了,如果单纯的只向右和下的话可以用三维标记 dp[ i ] [ j ] [ k ] (

sky walking日志采集以及注意事项

文章目录 1,sky walking日志采集功能概述2,采集log4j2日志3,采集logback日志4,效果展示5,注意事项 1,sky walking日志采集功能概述 在介绍Sky walking日志采集功能之前,最好在系统学习一遍日志框架,这里推荐楠哥的日志框架 在实际项目中我们需要将项目中的日志采集到sky walking中以便于我们能够快速排查问题,sky walkin