题目大意:给定一棵树,每一个点都从当前位置走到距离最远的位置,1~n的连续区间中最大并且走的最远距离差值不超过Q的区间右多大。

思路:首先求出每个点能到达的最远距离,这一步有两种做法:

第一种做法是树形DP,两次dfs,第一次求出从每个节点不同儿子节点所能走到最远距离maxlen[0],次远距离maxlen[1],以及走到最远距离时经过的儿子节点maxid。第二次dfs,每个点u能到达的最远距离就是不在u子树上的结点和u之间的最远距离len 与 u到子孙节点的最远距离中的最大值,在dfs的过程中更新len ,这就要用到我们第一次求得的maxid,假如当前儿子是maxid,当前边权值是w,那么儿子的len就为len+w,否则len为max(len,maxlen[0])+w.这一种做法代码量较小,但思路相对复杂。

第二种做法,考虑树的直径,不难发现所有点能到达的最远点一定为直径的两个端点之一,那么我们先两次dfs求出直径再两次dfs计算出所有点能到达的最远距离。这种做法相对好想。

求出了所有点能到的最远距离后我们初始化rmq,然后用对于每个询问用尺取法O(n)扫一遍,具体就是用两个指针一个指向起点,一个指向终点,如果当前差值大于q那么头指针后移否则尾指针后移并更新答案。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#include<ctime>
#define eps 1e-6
#define LL long long
#define pii pair<int, int>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;const int MAXN = 50500;
const int INF = 0x3f3f3f3f;
int n, m;
int maxlen[MAXN][2], maxid[MAXN], dist[MAXN];
struct Edge{int to,next;int w;
} edge[MAXN*2];
int head[MAXN],tot;
void init() {tot = 0;memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w) {edge[tot].to = v;edge[tot].w = w;edge[tot].next = head[u];head[u] = tot++;
}
void dfs1(int cur, int fa) {maxlen[cur][0]=0, maxid[cur]=cur, maxlen[cur][1]=-1; for(int i = head[cur]; i != -1; i = edge[i].next) {int u = edge[i].to, w = edge[i].w;if(u == fa) continue;dfs1(u, cur);if(maxlen[u][0]+w > maxlen[cur][0]) {maxlen[cur][1] = maxlen[cur][0];maxlen[cur][0] = maxlen[u][0] + w;maxid[cur] = u;}else if(maxlen[u][0]+w > maxlen[cur][1]) maxlen[cur][1]=maxlen[u][0]+w;}
}
void dfs2(int cur, int fa, int len) {  //len为cur的非子树到cur的最远距离 dist[cur] = max(maxlen[cur][0], len);for(int i = head[cur]; i != -1; i = edge[i].next) {int u = edge[i].to, w = edge[i].w;if(u == fa) continue;if(u == maxid[cur]) dfs2(u, cur, max(maxlen[cur][1],len)+w);else dfs2(u, cur, dist[cur]+w);}
}
int dmin[MAXN][20], dmax[MAXN][20];
void RMQ_init() {for(int i = 1; i <= n; i++) dmin[i][0] = dmax[i][0] = dist[i];for(int j = 1; (1<<j) <= n; j++) {for(int i = 1; i+(1<<j)-1 <= n; i++) {dmin[i][j] = min(dmin[i][j-1], dmin[i+(1<<(j-1))][j-1]);dmax[i][j] = max(dmax[i][j-1], dmax[i+(1<<(j-1))][j-1]);}}
}
int RMQ(int L, int R) {int k = 0;while((1<<(k+1)) <= R-L+1) k++;return max(dmax[L][k], dmax[R-(1<<k)+1][k])-min(dmin[L][k], dmin[R-(1<<k)+1][k]);
}
int main() {//freopen("input.txt", "r", stdin);while(scanf("%d%d", &n, &m)==2 && n) {init();for(int i = 1; i < n; i++) {int u, v, w; scanf("%d%d%d", &u, &v, &w);addedge(u, v, w);addedge(v, u, w);}dfs1(1, 0);dfs2(1, 0, 0);RMQ_init();while(m--) {int q; scanf("%d", &q);int ed=0, ans=0;for(int st = 1; st <= n; st++) {if(ed == n) continue;while(ed<n && RMQ(st, ed+1)<=q) ed++, ans=max(ans, ed-st+1);}printf("%d\n", ans);}}return 0;
}

HDU 4123 Bob’s Race(树形DP+RMQ)相关推荐

  1. HDU 1520 Anniversary party(树形dp)

    HDU 1520 Anniversary party(树形dp) 树形dp第一题!!! 题意很清晰,思路也很明确.很容易找到根节点,即最大的boss,通过根节点向下dp. 状态转移方程: int to ...

  2. 【题解】hdu 3586 Information Disturbing 二分 树形dp

    题目描述 Information Disturbing Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/65536 K (Jav ...

  3. HDU 3586 Information Disturbing (树形DP,二分)

    题意: 给定一个敌人的通信系统,是一棵树形,每个节点是一个敌人士兵,根节点是commander,叶子是前线,我们的目的是使得敌人的前线无法将消息传到commander,需要切断一些边,切断每条边需要一 ...

  4. 【HDU - 6567】Cotree(树形dp,思维)

    题干: Avin has two trees which are not connected. He asks you to add an edge between them to make them ...

  5. 【BZOJ2500】幸福的道路 树形DP+RMQ+双指针法

    [BZOJ2500]幸福的道路 Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的 ...

  6. 动态规划--树形DP

    动态规划--树形DP  1.什么是树型动态规划  顾名思义,树型动态规划就是在"树"的数据结构上的动态规划,平时作的动态规划都是线性的或者是建立在图上的,线性的动态规划有二种方向既 ...

  7. 两种解法-树形dp+二分+单调队列(或RMQ)-hdu-4123-Bob’s Race

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 题目大意: 给一棵树,n个节点,每条边有个权值,从每个点i出发有个不经过自己走过的点的最远距离 ...

  8. fwt优化+树形DP HDU 5909

    1 //fwt优化+树形DP HDU 5909 2 //见官方题解 3 // BestCoder Round #88 http://bestcoder.hdu.edu.cn/ 4 5 #include ...

  9. HDU 2196 Computer 树形DP经典题

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...

最新文章

  1. windows10删除更新的程序
  2. 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  3. linux scp远程拷贝文件及文件夹
  4. python程序经常被杀死之谜
  5. python unit test 访问开发代码_python unittest 源码分析
  6. 推荐一个可交互的 Attention 可视化工具!我的Transformer可解释性有救啦?
  7. DEDECMS之二 如何修改模板页
  8. Oracle 10g闪回恢复区 (Flash Recovery Area)
  9. codevs 4189 字典
  10. 查看环境列表_西门子COMOS软件开发定制学习8-查询列表间的数据交互
  11. c语言病毒恶搞代码大全,恶搞病毒代码案例分析
  12. 测试用例经典练习之淘宝app购物车测试用例
  13. Android9怎么剪辑音频,音频剪辑铃声制作
  14. ssm企业人事管理系统
  15. GBase 8a 集群维护工具C3介绍
  16. [学习经验] 孩子到底什么时候学习自然拼读和国际音标?
  17. ac86u原厂固件去广告_释放更多功能,华硕 AC86U 刷官改固件教程
  18. 蚂蚁金服副 CTO胡喜:从 BASIC 到 basic ,蚂蚁金服十五年技术架构演进之路
  19. Java笔试题(三)简答题
  20. 273222-06-3,(2S,4R)-Boc-4-amino-1-Fmoc-pyrrolidine-2-carboxylic acid,(2S,4R)-Fmoc-4-叔丁氧羰基氨基吡咯烷-2-甲酸

热门文章

  1. c语言单链表递增排序,单链表 基本操作(元素递增排序)
  2. 【RISC-V】risc-v架构学习笔记(架构初学)
  3. 什么是BSj架构?什么是CS架构?
  4. 【Python工具】Pycharm设置字体放大(缩小)快捷键
  5. 「物联网架构」MQTT 传感器数据流异常检测的深度学习KSQL UDF
  6. 一、mujoco安装
  7. 阿里云Linux镜像站
  8. Sizzle.js分析
  9. Go-Excelize API源码阅读(三十一)——ProtectSheet(sheet string, settings *SheetProtectionOptions)
  10. 有人知道报软件测试培训班需要多少钱吗?