题目描述

给出一棵树,定义一个点到一条路径的距离为这个点到这条路径上所有点的距离的最小值。求一条长度不超过s的路径,使得所有点到这条路径的距离的最大值最小。

输入

包含n行: 第1行,两个正整数n和s,中间用一个空格隔开。其中n为树网结点的个数,s为树网的核的长度的上界。设结点编号依次为1, 2, ..., n。 从第2行到第n行,每行给出3个用空格隔开的正整数,依次表示每一条边的两个端点编号和长度。例如,“2 4 7”表示连接结点2与4的边的长度为7。 所给的数据都是正确的,不必检验。

输出

只有一个非负整数,为指定意义下的最小偏心距。

样例输入

5 2
1 2 5
2 3 2
2 4 4
2 5 3

样例输出

5


题解

树的直径+双指针法+单调队列

首先易证路径一定在树的直径上(容易使用反证法证明)。

那么可以找出树的直径,然后考虑答案是怎么得到的:

(上边的直线是直径,红色的为选定路径)

由于保证了是直径,因此路径左边的贡献只有直径左端点到路径左端点,路径右边的贡献只有直径右端点到路径右端点;路径中的贡献为子树(图中三角形)中最远的点。

那么可以处理出每个点除直径的子树内最远的点作为每个点的权值。

然后考虑:随着左端点的移动,右端点的决策位置是单调不降的。因此可以使用双指针法并用单调队列维护区间最大值。

时间复杂度$O(n)$

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 500010
using namespace std;
int head[N] , to[N << 1] , len[N << 1] , next[N << 1] , cnt , fa[N] , deep[N] , vis[N] , v[N] , sum[N] , tot , q[N] , l , r;
inline void add(int x , int y , int z)
{
to[++cnt] = y , len[cnt] = z , next[cnt] = head[x] , head[x] = cnt;
}
void dfs(int x)
{
int i;
for(i = head[x] ; i ; i = next[i])
if(to[i] != fa[x])
fa[to[i]] = x , deep[to[i]] = deep[x] + len[i] , dfs(to[i]);
}
void getdis(int x , int now , int p)
{
int i;
v[p] = max(v[p] , now);
for(i = head[x] ; i ; i = next[i])
if(!vis[to[i]])
vis[to[i]] = 1 , getdis(to[i] , now + len[i] , p);
}
int main()
{
int n , m , i , x , y , z , mx , p = 0 , ans = 1 << 30;
scanf("%d%d" , &n , &m);
for(i = 1 ; i < n ; i ++ ) scanf("%d%d%d" , &x , &y , &z) , add(x , y , z) , add(y , x , z);
dfs(1) , mx = -1;
for(i = 1 ; i <= n ; i ++ )
if(deep[i] > mx)
x = i , mx = deep[i];
fa[x] = deep[x] = 0 , dfs(x) , mx = -1;
for(i = 1 ; i <= n ; i ++ )
if(deep[i] > mx)
y = i , mx = deep[i];
for(i = y ; i ; i = fa[i]) vis[i] = 1;
for(i = y ; i ; i = fa[i]) getdis(i , 0 , ++tot) , sum[tot + 1] = sum[tot] + deep[i] - deep[fa[i]];
for(i = 1 ; i <= tot ; i ++ )
{
while(p <= tot && sum[p + 1] - sum[i] <= m)
{
p ++ ;
while(l <= r && v[q[r]] <= v[p]) r -- ;
q[++r] = p;
}
ans = min(ans , max(max(sum[i] , sum[tot] - sum[p]) , v[q[l]]));
if(q[l] <= i) l ++ ;
}
printf("%d\n" , ans);
return 0;
}

【bzoj1999】[Noip2007]Core树网的核 树的直径+双指针法+单调队列的更多相关文章

  1. [bzoj1999][noip2007]Core树网的核

    好久没写题解了.这题不算太水就写一下题解. 话说回来,虽然不水但是挺裸.可以说题意即一半题解了. 我猜粘了题面也没有人去看的,所以直接人话题意了. 给一棵树,点数1e6,(当年noip的n当然是只有3 ...

  2. [BZOJ1999][codevs1167][Noip2007]Core树网的核

    [BZOJ1999][codevs1167][Noip2007]Core树网的核 试题描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(t ...

  3. BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP

    BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP Description 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T ...

  4. [Noip2007]Core树网的核

    嘟嘟嘟 首先求树的直径两次bfs即可,实际上bfs就是最短路,因为树上路径是唯一的,所以用任何一种遍历方法都行(spfa和dijkstra当然也可以). 可以证明,只要求出任意一条直径就行了,为什么呢 ...

  5. bzoj 1999: [Noip2007]Core树网的核【树的直径+单调队列】

    我要懒死了,所以依然是lyd的课件截图 注意是min{max(max(d[uk]),dis(u1,ui),dis(uj,un))},每次都从这三个的max里取min #include<iostr ...

  6. 洛谷 1099 ( bzoj 1999 ) [Noip2007]Core树网的核

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1999 <算法竞赛进阶指南>346页.https://www.cnblogs.co ...

  7. 【BZOJ1999】【NOIP2007】树网的核 单调队列优化DP

    题目描述 题目很长,大家自己去看吧. bzoj vijos 原题\(n\leq 300\) 加强版\(n\leq 500000\) 题解 这种东西当然要猜结论的啦,否则会比较麻烦. 结论1:如果有很多 ...

  8. 树网的核[树 floyd]

    描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边到有正整数的权,我们称T为树网(treebetwork),其中V,E分别表示结点与边的集合,W表示各边长度的集合,并设T ...

  9. 【DFS好题】BZOJ1999- [Noip2007]Core树网的核(数据加强版)

    NOIP的数据好水,一开始有好几个错结果NOIP数据就水过了?? [题目大意] 求无根树的直径上一段不超过S长的链,使得偏心距最小.具体概念见原题. [思路] 首先明确几个性质: (1)对于树中的任意 ...

随机推荐

  1. oracle 12.1.0.2中对象锁对系统的较大影响

    环境:oracle 12.1.0.2  rac ,4节点 一.概述 通常来说,如果是oltp应用,那么部署在rac上,是不错的注意. 但实现情况中,往往是混合类型,既有OLTP也有OLAP. 如果没有 ...

  2. 爬虫——Selenium与PhantomJS

    Selenium Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,类型像我们玩游戏用的按键精灵,可以按指定的命令自动操作,不同的是Selenium可以直接运行在浏览器上, ...

  3. NOIP模拟 candy

    题目描述 一天,小 DD 决定买一些糖果.他决定在两家不同的商店中买糖果,来体验更多的口味. 在每家商店中都有 nn 颗糖果,每颗糖果都有一个权值:愉悦度,代表小 DD 觉得这种糖果有多好吃.其中,第 ...

  4. 多线程编程之Apue3rd_Chapter15.10之posix信号量

    看了APUE的chapter15,只重点看了15.10,学习了posix信号量.Posix信号量比起xsi信号量的优点是性能更好,在Linux3.2.0平台上性能提升很大.其中命名信号量使用方法如下. ...

  5. Jetson tx1 安装cuda错误

    前两天安装Jetpack3.0的时候,看着网上的教程以为cuda会自动安装上,但是历经好几次安装,都安装不上cuda,也刷了好几次jetpack包.搜遍了网上的教程,也没有安装上.错误如下图所示: 这 ...

  6. shell重温---基础篇(输入/输出重定向)

        大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端.一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端.同样,一个命令通常将其输出写入到标准 ...

  7. 基于Ubuntu Server 16.04 LTS版本安装和部署Django之(三):设置上传文件夹权限(这里测试用完全共享)

    基于Ubuntu Server 16.04 LTS版本安装和部署Django之(一):安装Python3-pip和Django 基于Ubuntu Server 16.04 LTS版本安装和部署Djan ...

  8. 初步学习pg_control文件之二

    接前文:初步认识pg_control文件 继续学习,pg_control文件在何处形成的?是在initdb的时候,运用的函数如下: /* * This func must be called ONCE ...

  9. itop-4412开发板使用第一篇-信号量的学习使用

    1. 本次基于itop-4412研究下Linux信号量的使用方法. 2. 创建信号量的函数,信号量的头文件在那个路径?编译应用程序的话,头文件有3个路径,内核源码头文件,交叉编译器头文件,ubuntu ...

  10. mac 下 安装php扩展 - mcrypt

    由于自带的libmcrypt 可能版本低 另外通过brew安装的也不管用得去下载libmcrypt后编译安装 tar zxvf libmcrypt-2.5.8.tar.gz cd libmcrypt- ...