题目链接

  首先可以想到路径一定是在直径上的。

  然后对每个点dfs出不经过直径的以它开始的路径最大长度,记为dis

  然后就可以求出直径之后枚举左右端点,设左端点l右端点r,直径上点距离直径上起点的距离用sum[]表示

  则此时的$ans=max(max(sum[l],sum[End]-sum[r]),max(dis[i])l<=i<=r))$

  右面那个玩意可以单调队列维护。

  (然后我单调队列打反了变成维护最小值,GG。)

  

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cctype>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #define maxn 600030
  7. using namespace std;
  8. inline long long read(){
  9. long long num=,f=;
  10. char ch=getchar();
  11. while(!isdigit(ch)){
  12. if(ch=='-') f=-;
  13. ch=getchar();
  14. }
  15. while(isdigit(ch)){
  16. num=num*+ch-'';
  17. ch=getchar();
  18. }
  19. return num*f;
  20. }
  21.  
  22. struct Edge{
  23. int next,to,val;
  24. }edge[maxn*];
  25. int head[maxn],num;
  26. inline void add(int from,int to,int val){
  27. edge[++num]=(Edge){head[from],to,val};
  28. head[from]=num;
  29. }
  30.  
  31. int dis[maxn];
  32. bool vis[maxn];
  33. int stack[maxn],top;
  34. int sum[maxn];
  35. int End;
  36. int n,m;
  37.  
  38. void find(int x,int fa){
  39. for(int i=head[x];i;i=edge[i].next){
  40. int to=edge[i].to;
  41. if(to==fa) continue;
  42. dis[to]=dis[x]+edge[i].val;
  43. find(to,x);
  44. if(dis[End]<dis[to]) End=to;
  45. }
  46. }
  47.  
  48. void record(int x,int fa){
  49. if(x==End){
  50. stack[++top]=x;
  51. vis[x]=;
  52. return;
  53. }
  54. for(int i=head[x];i;i=edge[i].next){
  55. int to=edge[i].to;
  56. if(to==fa) continue;
  57. record(to,x);
  58. if(vis[to]){
  59. stack[++top]=x;
  60. sum[top]=sum[top-]+edge[i].val;
  61. vis[x]=;
  62. }
  63. }
  64. }
  65.  
  66. void calc(){
  67. find(,);
  68. dis[End]=;
  69. int Start=End;
  70. find(End,End);
  71. record(Start,Start);
  72. }
  73.  
  74. int dfs(int x,int fa){
  75. int ans=;
  76. for(int i=head[x];i;i=edge[i].next){
  77. int to=edge[i].to;
  78. if(to==fa||vis[to]==) continue;
  79. ans=max(ans,dfs(to,x)+edge[i].val);
  80. }
  81. return ans;
  82. }
  83.  
  84. int que[maxn],h=,t;
  85.  
  86. int main(){
  87. n=read(),m=read();
  88. for(int i=;i<n;++i){
  89. int from=read(),to=read(),val=read();
  90. add(from,to,val);
  91. add(to,from,val);
  92. }
  93. calc();
  94. for(int i=;i<=top;++i) dis[i]=dfs(stack[i],stack[i]);
  95. int rig=;int ans=0x7fffffff;
  96. for(int i=;i<=top;++i){
  97. int le=sum[i];
  98. while(sum[rig+]-sum[i]<=m&&rig<top){
  99. rig++;
  100. while(h<=t&&dis[que[t]]<=dis[rig]) t--;
  101. que[++t]=rig;
  102. while(h<=t&&que[h]<i) h++;
  103. int now=max(le,max(sum[top]-sum[rig],dis[que[h]]));
  104. ans=min(ans,now);
  105. }
  106. }
  107. printf("%d\n",ans);
  108. return ;
  109. }

【Luogu】P2491消防(单调队列)的更多相关文章

  1. [SDOI2011]消防(单调队列,树的直径,双指针)

     消防 2011年  时间限制: 2 s  空间限制: 256000 KB  题目等级 : 大师 Master   题目描述 Description 某个国家有n个城市,这n个城市中任意两个都连通且有 ...

  2. luogu 2827 蚯蚓 单调队列/优先队列

    易知可利用优先队列选取最大值: 但是通过分析可知,先取出的蚯蚓分开后仍然要比后分的长,所以可直接利用单调队列找队头即可,分三个单调队列,分别找未切割,切割,切割2三种情况 #include<bi ...

  3. luogu 2569 股票交易 单调队列dp

    注意转移方程 分1.凭空买 2.不买不卖 3.在原来基础上买 4.在原来基础上卖 四种情况 head=1,tail=0;再判断一下head<=tail也可以 #include<bits/s ...

  4. Luogu 1020 导弹拦截(动态规划,最长不下降子序列,二分,STL运用,贪心,单调队列)

    Luogu 1020 导弹拦截(动态规划,最长不下降子序列,二分,STL运用,贪心,单调队列) Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺 ...

  5. 【BZOJ2282】[Sdoi2011]消防 树形DP+双指针法+单调队列

    [BZOJ2282][Sdoi2011]消防 Description 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这 ...

  6. Luogu【P1725】琪露诺(单调队列,DP)

    本文是笔者第二篇解题报告.从现在开始,会将练的一些题发到博客上并归类到"解题报告"标签中. 琪露诺是这样一道题 这道题可以用纯DP做,但是据说会超时.(为什么?看起来过河这题比它数 ...

  7. BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2806 (luogu) https://www.luogu.org/pro ...

  8. [luogu P1776] 宝物筛选 解题报告(单调队列优化DP)

    题目链接: https://www.luogu.org/problemnew/show/P1776 题目: 终于,破解了千年的难题.小FF找到了王室的宝物室,里面堆满了无数价值连城的宝物……这下小FF ...

  9. luogu 3084 单调队列+dp

    注意处理出两个数组: r[i] 能覆盖i点的区间的左端点最小值(覆盖左侧最远处) l[i] i不能覆盖的区间的左端点左端点最大值 在该区间内寻找用来更新f[i] 答案的 j 即 l[i]<= j ...

随机推荐

  1. Spark的调度

    作业调度简介 设计者将资源进行不同粒度的抽象建模,然后将资源统一放入调度器,通过一定的算法进行调度,最终要达到高吞吐或者低访问延时的目的. Spark在各种运行模式中各个角色实现的功能基本一致,只不过 ...

  2. 用ComboBox控件制作浏览器网址输入框

    实现效果: 知识运用: ComboBox控件的FindString public int FindString(string s) //查找数据项集合中指定数据项的索引 和Select方法 publi ...

  3. jquery iCheck 插件

    1 官网:http://www.bootcss.com/p/icheck/#download 2 博客:https://www.cnblogs.com/xcsn/p/6307610.html http ...

  4. datetime 插件

    1  写一段文本 <div id="nomarl-wrap"> <div class="form-group"> <label c ...

  5. 梁勇(Danniel Liang) java教材例题:java程序购买额按税率求营业税 java中数值保留2位小数的方法

    package com.swift; import java.util.Scanner; public class PurchaseTaxDecimalsTwo { public static voi ...

  6. java链接MySQL数据库时使用com.mysql.jdbc.Connection的包会出红线问题 java.lang.ClassNotFoundException: com.mysql.jdbc.Driver问题

    package com.swift; //这里导入的包是java.sql.Connection而不是com.mysql.jdbc.Connection import java.sql.Connecti ...

  7. SSH实验

    跳板机实验1:本地转发 实验环境: 三台主机:A,B,C 目标A与C通过telnet连接 A主机和B,C主机之间有防火墙相隔,A与B之间可以通过SSH协议连接,BC之间可以通过telnet协议连接 环 ...

  8. hashlib模块常用功能

    什么是hash hash是一种算法,该算法接受传入的内容,经过运算得到一串hash值 如果把hash算法比喻为一座工厂 那传给hash算法的内容就是原材料 生成的hash值就是生产出的产品 2.为何要 ...

  9. 【Ecshop】后台菜单与权限管理

    主要php文件: 1,admin/includes/inc_menu.php ECSHOP管理中心菜单数组--配置菜单组及URL 2,languages/zh_cn/admin/common.php  ...

  10. 微信小程序 onLoad 函数

    小程序注册完成后,加载页面,触发onLoad方法. 页面载入后触发onShow方法,显示页面. 首次显示页面,会触发onReady方法,渲染页面元素和样式,一个页面只会调用一次. 当小程序后台运行或跳 ...