消防(树上直径)

题目描述

某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000)。
这个国家的人对火焰有超越宇宙的热情,所以这个国家最兴旺的行业是消防业。由于政府对国民的热情忍无可忍(大量的消防经费开销)可是却又无可奈何(总统竞选的国民支持率),所以只能想尽方法提高消防能力。
现在这个国家的经费足以在一条边长度和不超过s的路径(两端都是城市)上建立消防枢纽,为了尽量提高枢纽的利用率,要求其他所有城市到这条路径的距离的最大值最小。
你受命监管这个项目,你当然需要知道应该把枢纽建立在什么位置上。

输入格式

输入包含n行:
第1行,两个正整数n和s,中间用一个空格隔开。其中n为城市的个数,s为路径长度的上界。设结点编号以此为1,2,……,n。
从第2行到第n行,每行给出3个用空格隔开的正整数,依次表示每一条边的两个端点编号和长度。例如,“2 4 7”表示连接结点2与4的边的长度为7。

输出格式

输出包含一个非负整数,即所有城市到选择的路径的最大值,当然这个最大值必须是所有方案中最小的。

样例

样例输入

【样例输入1】
5 2
1 2 5
2 3 2
2 4 4
2 5 3
【样例输入2】
8 6
1 3 2
2 3 2 
3 4 6
4 5 3
4 6 4
4 7 2
7 8 3  

样例输出

Sample Output
【样例输出1】
5
【样例输出2】
5

是不是很久没粘题面了。

一道树上直径的好题。

首先我们要找出直径,因为直径的中点一定距其他点的最大值最小,

设直径的长度为d,假设有其他点到中点距离大于d/2,那么肯定会形成新的直径和端点

那么我们可以考虑当取出直径的一段时,离直径最长的点会是什么点

发现,要么是直径的两端点,要么是非直径点,因为非直径点是一定的,我们可以预处理出,

剩下的我们只需要用单调队列找出覆盖在直径上的小于s的路径就好了。

原文地址:https://www.cnblogs.com/Wwb123/p/11610995.html