洛谷 1099 ( bzoj 1999 ) [Noip2007]Core树网的核
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1999
《算法竞赛进阶指南》346页。https://www.cnblogs.com/shenben/p/5895325.html
1.用随便一条直径算就行了。
由题知所有直径都有交点。故有公共部分。
如果分叉形状。核选在分叉后的地方,偏心距一定它是到直径的较远端点的距离。不然直径就不是最长的了。
核选在分叉前的地方,偏心距一定比上述距离短。不然直径就不是最长的了。所以选在分叉前的地方一定更优。
所有的分叉前的地方就是所有直径的公共部分。所以随便找一条直径求就行了。
2.核在不超限的情况下越长越好。所以在直径上弄两个指针,枚举核就是O(n)的了。
3.max( max( dis[k] ) , dis[ s~i ] , dis[ j~t ] ) ( k是 i ~ j 连出去的子树中的点 ) <==> max( max( dis[k] ) , dis[ s~i ] , dis[ j~t ] ) ( k是所有的点 )
之所以等价是因为对于一段核,直径上别的部分连出去的子树中的点到直径的距离一定小于第一个式子中的三个部分。不然直径就不是最长的了。
然后 max( dis[k] ) ( k是所有的点 ) 就是一个定值了!只要找一下上式后两个部分的min,最后和max( dis[k] )取个max就行了。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=5e5+;
int n,s,head[N],xnt,fa[N],dis[N],ans,l0,l1;
bool vis[N];
struct Edge{
int next,to,w;
Edge(int n=,int t=,int w=):next(n),to(t),w(w) {}
}edge[N<<];
int rdn()
{
int ret=,fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=-;ch=getchar();}
while(ch>=''&&ch<='')(ret*=)+=ch-'',ch=getchar();
return ret*fx;
}
void add(int x,int y,int z)
{
edge[++xnt]=Edge(head[x],y,z);head[x]=xnt;
edge[++xnt]=Edge(head[y],x,z);head[y]=xnt;
}
void dfs(int cr,int f)
{
for(int i=head[cr],v;i;i=edge[i].next)
if((v=edge[i].to)!=f&&!vis[v])
{
dis[v]=dis[cr]+edge[i].w;
fa[v]=cr;dfs(v,cr);
}
}
int main()
{
n=rdn();s=rdn();int x,y,z;
for(int i=;i<n;i++)
{
x=rdn();y=rdn();z=rdn();
add(x,y,z);
}
dfs(,);l0=;
for(int i=;i<=n;i++)if(dis[i]>dis[l0])l0=i;
dis[l0]=;fa[l0]=;dfs(l0,);
for(int i=;i<=n;i++)if(dis[i]>dis[l1])l1=i;
ans=0x7fffffff;int j=l1;
for(int i=l1;i;i=fa[i])
{
vis[i]=;
while(j&&dis[i]-dis[fa[j]]<=s)j=fa[j];
ans=min(ans,max(dis[l1]-dis[i],dis[j]));
}
for(int i=;i<=n;i++)if(vis[i])dis[i]=,dfs(i,);
for(int i=;i<=n;i++)ans=max(ans,dis[i]);
printf("%d",ans);
return ;
}
洛谷 1099 ( bzoj 1999 ) [Noip2007]Core树网的核的更多相关文章
- bzoj 1999: [Noip2007]Core树网的核【树的直径+单调队列】
我要懒死了,所以依然是lyd的课件截图 注意是min{max(max(d[uk]),dis(u1,ui),dis(uj,un))},每次都从这三个的max里取min #include<iostr ...
- [BZOJ1999][codevs1167][Noip2007]Core树网的核
[BZOJ1999][codevs1167][Noip2007]Core树网的核 试题描述 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(t ...
- BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP
BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP Description 设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T ...
- 【bzoj1999】[Noip2007]Core树网的核 树的直径+双指针法+单调队列
题目描述 给出一棵树,定义一个点到一条路径的距离为这个点到这条路径上所有点的距离的最小值.求一条长度不超过s的路径,使得所有点到这条路径的距离的最大值最小. 输入 包含n行: 第1行,两个正整数n和s ...
- [bzoj1999][noip2007]Core树网的核
好久没写题解了.这题不算太水就写一下题解. 话说回来,虽然不水但是挺裸.可以说题意即一半题解了. 我猜粘了题面也没有人去看的,所以直接人话题意了. 给一棵树,点数1e6,(当年noip的n当然是只有3 ...
- [Noip2007]Core树网的核
嘟嘟嘟 首先求树的直径两次bfs即可,实际上bfs就是最短路,因为树上路径是唯一的,所以用任何一种遍历方法都行(spfa和dijkstra当然也可以). 可以证明,只要求出任意一条直径就行了,为什么呢 ...
- BZOJ1999或洛谷1099&BZOJ2282或洛谷2491 树网的核&[SDOI2011]消防
一道树的直径 树网的核 BZOJ原题链接 树网的核 洛谷原题链接 消防 BZOJ原题链接 消防 洛谷原题链接 一份代码四倍经验,爽 显然要先随便找一条直径,然后直接枚举核的两个端点,对每一次枚举的核遍 ...
- 洛谷1099 [NOIP2007] 树网的核
链接https://www.luogu.org/problemnew/show/P1099 题目描述 设T=(V,E,W)是一个无圈且连通的无向图(也称为无根树),每条边到有正整数的权,我们称TTT为 ...
- 洛谷 P3307: bzoj 3202: [SDOI2013] 项链
题目传送门:洛谷P3307.这题在bzoj上是权限题. 题意简述: 这题分为两个部分: ① 有一些珠子,每个珠子可以看成一个无序三元组.三元组要满足三个数都在$1$到$m$之间,并且三个数互质,两个珠 ...
随机推荐
- SpringBoot AOP示例
AOP主要注解: @Aspect,作用在类上,说明这是一个Aspect切面类. @Pointcut,用来描述,你需要在哪些类的哪些方法中植入你的代码. @Adive,与Pointcut配合使用,主要说 ...
- Python 面向对象的综合应用
# 面向对象的综合应用 # 计算器:实现一些基本的计算操作,已经打印结果 # --------------- 代码1 ---------------------- def add(x, y): ret ...
- Luogu-3648 [APIO2014]序列分割
Luogu-3648 [APIO2014]序列分割 题目链接 题解: 首先要发现一个重要的性质:分割的顺序是不会影响答案的 证明: 首先对于没有交的两段区间,显然先后顺序改变不会有影响 而对于在同一段 ...
- spring注解方式注入bean
用注解的方式注入bean,spring的配置文件也要增加一些约束和导入注解所在的包 applicationContext.xml <?xml version="1.0" en ...
- MySQL 触发器简单实例 - 转载
MySQL 触发器简单实例 触发器:可以更新,删除,插入触发器,不同种类的触发器可以存在于同一个表,但同种类的不能有多个.一个更新.一个删除是可以共存的. ~~语法~~ CREATE TRIGGER ...
- Source Insight 插件
一提到外挂程序,大家肯定都不陌生,QQ就有很多个版本的去广告外挂,很多游戏也有用于扩展功能或者作弊的工具,其中很多也是以外挂的形式提供的.外挂和插件的区别在于插件通常依赖于程序的支持,如果程序不支持插 ...
- CSS3 网格布局(grid-layout)基础知识 - 网格模板属性(grid-template)使用说明
CSS3引入了新的网格布局(grid layout),以适应显示和设计技术的发展(尤其是移动设备优先的响应式设计). 主要目标是建立一个稳定可预料且语义正确的网页布局模式,用来替代过往表现不稳定且繁琐 ...
- 计蒜客button 概率
中文题意不多说,这题主要是数据太大,无法递推,所以用欧拉常数来解决 对于调和级数1/1+1/2+...+1/n=ln(n)+C+1/(2*n),C为欧拉常数,再加上ceil向上取整就可以了 #incl ...
- IOS-导航路线
1.可以将需要导航的位置丢给系统自带的APP进行导航 2.发送网络请求到公司服务器获取导航数据, 然后自己手动绘制导航 3.利用三方SDK实现导航(百度) >当点击开始导航时获取用户输入的起点和 ...
- 【spark】示例:连接操作
我们有这样两个文件 任务:找出用户评分平均值大于4的电影. 我们看两个文件结果,第一个文件有电影的ID和名字,第二个文件有电影的ID和所有用户的评分 对于任务结果所需要的数据为电影ID,电影名字,平均 ...