到路径的距离就是到路径上的点最近的距离
首先看到最大值最小不难想到二分答案
下面的问题就是怎么判断,显然我们是不能穷举路径的
我们要找出消防路径的性质
仔细研究就会发现消防路径一定是树的直径的一段,这样必然最右
证明很简单,我们可以利用反证法解决,通过证明可以发现这个直径随便选一条就可以了
我们把树的直径拎出来,把直径上的点挂在直径下面(就相当于晾衣服一样……)
然后我们可以算出直径上每个点i的子树到i的最大距离,然后就很好处理了

 type node=record
po,dis,next:longint;
end; var q,d1,d2,p1,p2,p,f:array[..] of longint;
e:array[..] of node;
v:array[..] of boolean;
t,n,m,s,l,r,i,x,y,z,len,w:longint; function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end; procedure add(x,y,z:longint);
begin
inc(len);
e[len].po:=y;
e[len].dis:=z;
e[len].next:=p[x];
p[x]:=len;
end; procedure dfs(x:longint);
var i,y:longint;
begin
v[x]:=true;
i:=p[x];
while i<> do
begin
y:=e[i].po;
if not v[y] then
begin
dfs(y);
if d1[y]+e[i].dis>d1[x] then
begin
d2[x]:=d1[x];
p2[x]:=p1[x]; //p1,p2记录的是这棵子树最长次长延伸的方向
d1[x]:=d1[y]+e[i].dis;
p1[x]:=i;
end
else if d1[y]+e[i].dis>d2[x] then
begin
d2[x]:=d1[y]+e[i].dis;
p2[x]:=i;
end;
end;
i:=e[i].next;
end;
if d1[x]+d2[x]>d1[w]+d2[w] then w:=x;
end; procedure dfss(x:longint);
var i,y:longint;
begin
i:=p[x];
v[x]:=true;
while i<> do
begin
y:=e[i].po;
if not v[y] then
begin
dfss(y);
f[x]:=max(f[x],f[y]+e[i].dis);
end;
i:=e[i].next;
end;
end; procedure getl(x:longint);
begin
if p1[x]<> then getl(e[p1[x]].po);
inc(t); q[t]:=x; v[x]:=true;
end; function check(len:longint):boolean;
var l,r,w:longint;
begin
l:=;
r:=t;
w:=f[q[]];
while (l<t) and (w+d1[q[l+]]<=len) do //在满足最长距离不超过len的情况下使路径尽可能短
begin
inc(l);
w:=max(w,f[q[l]]-d1[q[l]]);
end;
w:=f[q[t]]+d1[q[t]];
while (r>l) and (w-d1[q[r-]]<=len) do
begin
dec(r);
w:=max(w,f[q[r]]+d1[q[r]]);
end;
if d1[q[r]]-d1[q[l]]<=s then exit(true)
else exit(false);
end; begin
readln(n,s);
for i:= to n- do
begin
readln(x,y,z);
add(x,y,z);
add(y,x,z);
end;
dfs();
fillchar(v,sizeof(v),false);
getl(w);
x:=w; i:=p2[x];
while i<> do
begin
y:=e[i].po;
inc(t); q[t]:=e[i].po; v[y]:=true;
d1[y]:=d1[x]+e[i].dis; //把直径提出来作为一条链,d1相当于到链头的距离
i:=p1[y]; x:=y;
end;
r:=d1[x];
for i:= to t do
begin
x:=q[i];
dfss(x);
l:=max(l,f[x]); //f处理的是子树最深距离
end;
if s<d1[q[t]] then
begin
while l<=r do
begin
m:=(l+r) shr ;
if check(m) then r:=m-
else l:=m+;
end;
end;
writeln(l);
end.

bzoj2282的更多相关文章

  1. BZOJ2282 SDOI2011消防/NOIP2007树网的核(二分答案+树形dp)

    要求最大值最小容易想到二分答案.首先对每个点求出子树中与其最远的距离是多少,二分答案后就可以标记上一些必须在所选择路径中的点,并且这些点是不应存在祖先关系的.那么如果剩下的点数量>=3,显然该答 ...

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

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

  3. BZOJ2282: [Sdoi2011]消防

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2282 答案一定是在直径上的一段,然后答案一定不会小于不在直径上的点到直径的距离(要是可以的话那 ...

  4. BZOJ1999或洛谷1099&BZOJ2282或洛谷2491 树网的核&[SDOI2011]消防

    一道树的直径 树网的核 BZOJ原题链接 树网的核 洛谷原题链接 消防 BZOJ原题链接 消防 洛谷原题链接 一份代码四倍经验,爽 显然要先随便找一条直径,然后直接枚举核的两个端点,对每一次枚举的核遍 ...

  5. [BZOJ2282]消防

    Description 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个国家 ...

  6. [Bzoj2282]消防(二分答案+树的直径)

    Description 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个国家 ...

  7. 【bzoj2282】[Sdoi2011]消防

    两次bfs可得直径,答案一定不会小于所有点到直径的距离最大值,只要把直径上的边权设为0,任选直径上一点bfs可得将最大值作为二分下界,二分直径左右端点的舍弃部分 #include<algorit ...

  8. NOIP2007 树网的核 && [BZOJ2282][Sdoi2011]消防

    NOIP2007 树网的核 树的直径的最长性是一个很有用的概念,可能对一些题都帮助. 树的直径给定一棵树,树中每条边都有一个权值,树中两点之间的距离定义为连接两点的路径边权之和.树中最远的两个节点之间 ...

  9. [转载]hzwer的bzoj题单

    counter: 664BZOJ1601 BZOJ1003 BZOJ1002 BZOJ1192 BZOJ1303 BZOJ1270 BZOJ3039 BZOJ1191 BZOJ1059 BZOJ120 ...

随机推荐

  1. Go与GUI——GO语言的图形界面Walk

    GO没有原生的界面库,所以不能直接用来写GUI界面.但最近互联网上已经涌现出不少成熟.好用的第三方界面库.使用它们,就同样可以写出同C#.C++的界面.而且效率还更胜一筹. 关于Walk界面库(官方介 ...

  2. python拆分excel脚本

    因为需要将一个很大的excel按500条拆分为多个excel,手工操作实在太麻烦,就写了个python小脚本,现在是分为了多个sheet页,使用者可根据自己实际情况修改成多个文件的形式 #!/usr/ ...

  3. 13_ServletContext对象

    [简介] ServletContext即Servlet上下文对象,该对象表示当前的web应用环境信息,一个Web应用只会创建一个ServletContext对象. Web容器启动的时候,它会为每个We ...

  4. 阅读 Linux 内核源码

    阅读Linux Kernel Source Code 假如你在Linux系统下面阅读Linux内核源代码,那么需要准备一些工具. ①Linux的内核源码 内核源码的下载地址:Index of /pub ...

  5. Visual Stuido 2015 Community 使用 GitHub 插件

    微软在Visual Studio 2015产品中,深度整合了GitHub,让VS用户更方便的使用GitHub的服务. 新闻链接: Announcing the GitHub Extension for ...

  6. wait(...) notify() notifyAll()

    简介 wait.notify.notifyAll是Java中3个与线程有关的方法,它们都是Object类中的方法. 其中,wait方法有3个重载形式: 1.wait() 2.wait(long tim ...

  7. C#语法需要注意的地方

    笔试中遇到的一些C#语法方面的问题,由于平时很少用到,笔试的时候模棱两可,现在做一个笔记. using System; using System.Collections.Generic; using ...

  8. Percona-Server-5.5.15源码安装

    [root@localhost rpm]# ll total 19148 -rw-r--r-- 1 root root   562628 Jan 18  2007 bison-2.3-2.1.x86_ ...

  9. 关于css中overflow:hidden的使用

    overflow:hidden有两个用处经常用到: 1.通过设定自身的高度,加上overflow:hidden可以隐藏超过容器本身的内容:     但是,小编在以往的使用中,发现了一个问题,只要父级容 ...

  10. jsonp使用规范

    这两天花了很多时间弄研究jsonp这个东西, 可是无论我怎么弄..TMD就是不进入success函数,并且一直进入error函数...让我着实DT啊. 可以看下我之间的提问(这就是我遇到的烦恼).. ...