题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4123

题意:

  给你一棵树,n个节点,每条边有长度。

  然后有m个询问,每个询问给定一个q值。

  设dis[i]为:从节点i出发,不重复经过节点,所能够走的最远距离。

  每次询问问你:区间[l,r]最长能有多长,同时保证 max{dis[i]} - min{dis[i]} <= q (i∈[l,r])

题解:

  首先有一个结论:

    从树上的任意一个节点出发,尽可能往远走,最终一定会到达树的直径的两个端点之一。

  所以先两遍dfs1,找出直径的两个端点。

  然后分别从两个端点dfs2,求出所有节点的dis[i]。

  因为节点必须选编号连续的一段区间,所以可以用到单调队列。

  枚举每个节点i加入队首。

  然后对于每个i,不断地丢掉队尾pos++,直到当前的区间[pos,i]符合条件。

  那么每次都需要判断是否有 max{dis[i]} - min{dis[i]} <= q (i∈[pos,i])

  这就要用到st表了,然后O(1)判断就好。

AC Code:

  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <vector>
  5. #define MAX_N 50005
  6. #define MAX_K 20
  7.  
  8. using namespace std;
  9.  
  10. struct Edge
  11. {
  12. int dest;
  13. int len;
  14. Edge(int _dest,int _len)
  15. {
  16. dest=_dest;
  17. len=_len;
  18. }
  19. Edge(){}
  20. };
  21.  
  22. int n,m;
  23. int maxd;
  24. int st,ed;
  25. int dis[MAX_N];
  26. int lg[MAX_N];
  27. int maxt[MAX_N][MAX_K];
  28. int mint[MAX_N][MAX_K];
  29. vector<Edge> edge[MAX_N];
  30.  
  31. void read()
  32. {
  33. for(int i=;i<=n;i++) edge[i].clear();
  34. int x,y,z;
  35. for(int i=;i<n;i++)
  36. {
  37. cin>>x>>y>>z;
  38. edge[x].push_back(Edge(y,z));
  39. edge[y].push_back(Edge(x,z));
  40. }
  41. }
  42.  
  43. void dfs1(int now,int p,int d,int &v)
  44. {
  45. if(d>maxd)
  46. {
  47. maxd=d;
  48. v=now;
  49. }
  50. for(int i=;i<edge[now].size();i++)
  51. {
  52. Edge temp=edge[now][i];
  53. if(temp.dest!=p) dfs1(temp.dest,now,d+temp.len,v);
  54. }
  55. }
  56.  
  57. void dfs2(int now,int p,int d)
  58. {
  59. dis[now]=max(dis[now],d);
  60. for(int i=;i<edge[now].size();i++)
  61. {
  62. Edge temp=edge[now][i];
  63. if(temp.dest!=p) dfs2(temp.dest,now,d+temp.len);
  64. }
  65. }
  66.  
  67. void init_st()
  68. {
  69. lg[]=-;
  70. for(int i=;i<=n;i++)
  71. {
  72. lg[i]=lg[i>>]+;
  73. maxt[i][]=mint[i][]=dis[i];
  74. }
  75. for(int k=;(<<k)<=n;k++)
  76. {
  77. for(int i=;i+(<<k)-<=n;i++)
  78. {
  79. maxt[i][k]=max(maxt[i][k-],maxt[i+(<<(k-))][k-]);
  80. mint[i][k]=min(mint[i][k-],mint[i+(<<(k-))][k-]);
  81. }
  82. }
  83. }
  84.  
  85. int query_max(int l,int r)
  86. {
  87. int k=lg[r-l+];
  88. return max(maxt[l][k],maxt[r-(<<k)+][k]);
  89. }
  90.  
  91. int query_min(int l,int r)
  92. {
  93. int k=lg[r-l+];
  94. return min(mint[l][k],mint[r-(<<k)+][k]);
  95. }
  96.  
  97. void work()
  98. {
  99. maxd=-;
  100. dfs1(,-,,st);
  101. maxd=-;
  102. dfs1(st,-,,ed);
  103. memset(dis,-,sizeof(dis));
  104. dfs2(st,-,);
  105. dfs2(ed,-,);
  106. init_st();
  107. while(m--)
  108. {
  109. int q;
  110. cin>>q;
  111. int ans=;
  112. int pos=;
  113. for(int i=;i<=n;i++)
  114. {
  115. while(query_max(pos,i)-query_min(pos,i)>q) pos++;
  116. ans=max(ans,i-pos+);
  117. }
  118. cout<<ans<<endl;
  119. }
  120. }
  121.  
  122. int main()
  123. {
  124. while(cin>>n>>m)
  125. {
  126. if(n== && m==) break;
  127. read();
  128. work();
  129. }
  130. }

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

  1. HDU 4123 Bob’s Race 树的直径+单调队列

    题意: 给定n个点的带边权树Q个询问. 以下n-1行给出树 以下Q行每行一个数字表示询问. 首先求出dp[N] :dp[i]表示i点距离树上最远点的距离 询问u, 表示求出 dp 数组中最长的连续序列 ...

  2. 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 ...

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

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

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

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

  5. 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 ...

  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. 在Ubuntu 16.04下安装 virtualbox 5.2

        sudo sh -c 'echo "deb http://download.virtualbox.org/virtualbox/debian xenial contrib" ...

  2. 分析Memcached客户端如何把缓存数据分布到多个服务器上

    Memcached客户端可以设多个memcached服务器,它是如何把数据分发到各个服务器上,而使各个服务器负载平衡的呢? 可以看看.net版中的客户端中的源码,就可以知道 先看代码:   1 /// ...

  3. PHP性能之语言性能优化说明

    PHP语言性能优化优化啥? 如下图所示,PHP直接执行的是opcode,所以我们尽量减少扫描和转码解析. 这是我们第一个优化点,尽量使用PHP内置的函数代替我们的代码来实现同样的功能. 和我们自己写的 ...

  4. Python snap

    orderedDict enum sys.path 注册装饰器 装饰器检查 入参 Flask01 flask_script flask blue print functools.partial dns ...

  5. 什么是Java Server Pages?

    JSP全称Java Server Pages,是一种动态网页开发技术.它使用JSP标签在HTML网页中插入Java代码.标签通常以<%开头以%>结束. JSP是一种Java servlet ...

  6. saltstack之文件管理

    1.managed文件管理 /srv/salt/file/managed.sls /tmp/hyxc: file.managed: - source: - salt://files/hyxc - sa ...

  7. Spring Cloud 微服务四:熔断器Spring cloud hystrix

    前言:在微服务架构中,一般都是进程间通信,有可能调用链都比较长,当有底层某服务出现问题时,比如宕机,会导致调用方的服务失败,这样就会发生一连串的反映,造成系统资源被阻塞,最终可能造成雪崩.在sprin ...

  8. PHP-Manual的学习----【语言参考】----【类型】-----【string字符串型】

    1.一个字符串 string 就是由一系列的字符组成,其中每个字符等同于一个字节.这意味着 PHP 只能支持 256 的字符集,因此不支持 Unicode .2. string 最大可以达到 2GB. ...

  9. CentOS Linux解决网卡报错Bringing up interface eth0.....

    问题描述:在VMware里克隆出来的CentOS Linux,开机执行命令:ifconfig...没有看到eth0网卡.然后重启网卡又报以下错误:Bringing up interface eth0: ...

  10. mac安装iterm2

    1 安装 下载直接拖入应用中. 2 配置 2.1 配置oh my zsh https://github.com/robbyrussell/oh-my-zsh 一键安装: sh -c "$(c ...