题意:

给定n个点的带边权树Q个询问。

以下n-1行给出树

以下Q行每行一个数字表示询问。

首先求出dp[N] :dp[i]表示i点距离树上最远点的距离

询问u, 表示求出 dp 数组中最长的连续序列使得序列中最大值-最小值 <= u,输出这个序列的长度。

思路:

求dp数组就是求个树的直径然后dfs一下。

对于每一个询问,能够用一个单调队列维护一下。O(n)的回答。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <string>
  4. #include <iostream>
  5. #include <queue>
  6. #include <algorithm>
  7. #include <cmath>
  8. using namespace std;
  9. template <class T>
  10. inline bool rd(T &ret) {
  11. char c; int sgn;
  12. if(c=getchar(),c==EOF) return 0;
  13. while(c!='-'&&(c<'0'||c>'9')) c=getchar();
  14. sgn=(c=='-')?-1:1;
  15. ret=(c=='-')?0:(c-'0');
  16. while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
  17. ret*=sgn;
  18. return 1;
  19. }
  20. template <class T>
  21. inline void pt(T x) {
  22. if (x <0) {
  23. putchar('-');
  24. x = -x;
  25. }
  26. if(x>9) pt(x/10);
  27. putchar(x%10+'0');
  28. }
  29. typedef long long ll;
  30. const int N = 50010;
  31. int n, Q;
  32. struct Edge{
  33. int to, nex; ll dis;
  34. }edge[N<<1];
  35. struct node {
  36. int v, id;
  37. node() {}
  38. node(int _id, int _v) {
  39. id = _id; v = _v;
  40. }
  41. };
  42. int head[N], edgenum;
  43. void init(){for(int i = 1; i <= n; i++)head[i] = -1; edgenum = 0;}
  44. void add(int u, int v, ll d){
  45. Edge E = {v, head[u], d};
  46. edge[edgenum] = E;
  47. head[u] = edgenum++;
  48. }
  49. ll dis[N], dp[N], len;
  50. int Stack[N], top, pre[N], vis[N];
  51. int BFS(int x){
  52. for(int i = 1; i <= n; i++)
  53. dis[i] = -1;
  54. dis[x] = 0; pre[x] = -1;
  55. int far = x;
  56. queue<int> q; q.push(x);
  57. while(!q.empty())
  58. {
  59. int u = q.front(); q.pop();
  60. for(int i = head[u]; ~i; i = edge[i].nex){
  61. int v = edge[i].to;
  62. if(dis[v] == -1)
  63. {
  64. dis[v] = dis[u] + edge[i].dis;
  65. pre[v] = u;
  66. if(dis[far] < dis[v])
  67. far = v;
  68. q.push(v);
  69. }
  70. }
  71. }
  72. return far;
  73. }
  74. void dfs(int u){
  75. vis[u] = 1;
  76. for(int i = head[u]; ~i; i = edge[i].nex)
  77. {
  78. int v = edge[i].to;
  79. if(vis[v])continue;
  80. dp[v] = dp[u] + edge[i].dis;
  81. dfs(v);
  82. }
  83. }
  84. void build(){//预处理树的直径
  85. int E = BFS(1);
  86. int S = BFS(E);
  87. top = 0;
  88. int u = S;
  89. len = dis[S];
  90. for(int i = 1; i <= n; i++) vis[i] = 0;
  91. while(u!=-1)
  92. {
  93. Stack[top++] = u;
  94. dp[u] = max(dis[u], len - dis[u]);
  95. vis[u] = 1;
  96. u = pre[u];
  97. }
  98. for(int i = 0; i < top; i++) dfs(Stack[i]);
  99. }
  100. void input(){
  101. init(); ll d;
  102. for(int i = 1, u, v; i < n; i++)
  103. {
  104. rd(u); rd(v); rd(d);
  105. add(u, v, d); add(v, u, d);
  106. }
  107. }
  108.  
  109. node mx[N], mi[N];
  110. int h1, t1, h2, t2;
  111. int main() {
  112. int v, idx, ans;
  113. while(cin>>n>>Q, n+Q) {
  114. input();
  115. build();
  116. while(Q--)
  117. {
  118. rd(v);
  119. ans = h1 = t1 = h2 = t2 = 0;
  120. idx = 1;
  121. for (int i = 1; i <= n; ++i) {
  122. while (h1!=t1 && mx[t1-1].v <= dp[i])
  123. -- t1;
  124. mx[t1++] = node(i, dp[i]);
  125. while (h2!=t2 && mi[t2-1].v >= dp[i])
  126. -- t2;
  127. mi[t2++] = node(i, dp[i]);
  128. while (h1!=t1&&h2!=t2) {
  129. if (mx[h1].v-mi[h2].v>v)
  130. ++ idx;
  131. else
  132. break;
  133. while (h1!=t1&&mx[h1].id<idx)
  134. ++h1;
  135. while (h2!=t2&&mi[h2].id<idx)
  136. ++h2;
  137. }
  138. ans = max(ans, i-idx+1);
  139. }
  140. pt(ans);
  141. putchar('\n');
  142. }
  143. }
  144. return 0;
  145. }

HDU 4123 Bob’s Race 树的直径+单调队列的更多相关文章

  1. HDU 4123 Bob’s Race 树的直径 RMQ

    Bob’s Race Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=41 ...

  2. hdu 4123 Bob’s Race 树的直径+rmq+尺取

    Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Probl ...

  3. POJ 3162 Walking Race(树的直径+单调队列)

    题目大意:对一棵树,求出从每个结点出发能到走的最长距离(每个结点最多只能经过一次),将这些距离按排成一个数组得到dis[1],dis[2],dis[3]……dis[n] ,在数列的dis中求一个最长的 ...

  4. HDU 4123 Bob’s Race 树的直径+ST表

    Bob’s Race Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=41 ...

  5. HDU 4123 Bob's Race:树的直径 + 单调队列 + st表

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4123 题意: 给你一棵树,n个节点,每条边有长度. 然后有m个询问,每个询问给定一个q值. 设dis[ ...

  6. HDU 4123 Bob’s Race 树形dp+单调队列

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4123 Time Limit: 5000/2000 MS (Java/Others) Memory L ...

  7. hdu 4123 Bob’s Race (dfs树上最远距离+RMQ)

    C - Bob’s Race Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Subm ...

  8. HDU 4123(树的直径+单调队列)

    Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. HDU 4123 Bob’s Race(树形DP,rmq)

    Bob’s Race Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. Android 通过系统使用NotificationListenerService 监听各种Notification的用法

    NotificationListenerService是通过系统调起的服务,当有应用发起通知的时候,系统会将通知的动作和信息回调给NotificationListenerService. 在继承Not ...

  2. 将 Android* x86 NDK 供 Eclipse* 而移植 NDK 演示示例应用程序

    目标 面向 Eclipse (ADT) 的 Android 插件如今支持基于 NDK 的应用开发. 其可自己主动生成项目和构件文件以及代码存根.并可集成到整个 Android 应用开发中(构建原生库. ...

  3. [2014 Regional]牡丹江 H Hierarchical Notation 做题记录

    主妇:老年人谁是炮灰牡丹江,我们的团队只是做同步大赛 他决定开爆震H什么时候,A 5min 1Y.I在该限制后,纠结了很久30min+ 1Y,神继续承担各种位置卡D在,hpp见B我认为这是非常熟悉的研 ...

  4. facade pattern

    外观模式是一种使用频率非常高的设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,使子系统与客户端的耦合度降低,且客户端调用非常方便.外观模式并不给系 ...

  5. 【设计模式】Template Method模式

    OO基金会 封装 多态 继承 OO原则 封装变化 多用组合,少用继承 针对接口编程.不针对实现编程 为交互对象的松耦合设计而努力 类应该对扩展开放,对改动关闭 依赖抽象,不要依赖详细类 仅仅和朋友交谈 ...

  6. 说说nio2

    利不百不变法,功不十不易器 为什么会出现nio,之前的io有什么问题? 请先看 说说nio1 nio类图例如以下 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZX ...

  7. linux文件打开模式

     文件打开 int open(const char *pathname, int flags, mode_t mode); 普通方式(Canonical mode) flags中没有设置O_SYN ...

  8. HTML5之Canvas影片广场

    HTML5之Canvas影片广场 1.设计源代码 <!DOCTYPE html> <head> <meta charset="utf-8" /> ...

  9. android传感器;摇抽奖功能

    package com.kane.sensortest; import java.util.Random; import android.hardware.Sensor; import android ...

  10. Android开发经验—不要指望类finalize干活的方法做你想要什么

    之所以专门写了一篇文章finalize方法博客,这是通过在坑的方法引起的.一个读写jni当数据类.我在课堂上finalize该方法被调用来关闭文件和释放内存的方法.频繁调用这个类的时候在JNI里面报异 ...