BZOJ4379 POI2015 Modernizacja autostrady


Description

给定一棵无根树,边权都是1,请去掉一条边并加上一条新边,定义直径为最远的两个点的距离,请输出所有可能的新树的直径的最小值和最大值。

Input

第一行包含一个正整数n(3<=n<=500000),表示这棵树的点数。

接下来n-1行,每行包含两个正整数u,v(1<=u,v<=n),表示u与v之间有一条边。

Output

第一行输出五个正整数k,x1,y1,x2,y2,其中k表示新树直径的最小值,x1,y1表示这种情况下要去掉的边的两端点,x2,y2表示这种情况下要加上的边的两端点。

第二行输出五个正整数k,x1,y1,x2,y2,其中k表示新树直径的最大值,x1,y1表示这种情况下要去掉的边的两端点,x2,y2表示这种情况下要加上的边的两端点。

若有多组最优解,输出任意一组。

Sample Input

6
1 2
2 3
2 4
4 5
6 5

Sample Output

3 4 2 2 5
5 2 1 1 6


Solution:

一道树的直径裸题。

首先要抛开打印解的部分,因为求得应该断哪个点之后,我们可以直接在两个连通块内找到直径端点或者最靠近直径中点的点,时间复杂度是 O(n) 的。结果我一开始并没有这么考虑,反而想着一边找最优解一边求方案,结果复杂度就无故增高,还增加了代码难度。

显然这个修改的边一定和这棵树的原直径,于是先将将树的直径抽离出来。接下来分别讨论两种最值的情况。

对于最小值,显然我们应该断在直径上。因为断在其他边不会改变直径的长度,而我们的目的又是让直径尽可能小。接下来对于断出的两个连通块,最后得到的连通块最小直径取决于以下三种情况:

  • 在连通块A内。
  • 在连通块B内。
  • 同时经过连通块A、B。

对于第三种情况,肯定是每个连通块最靠近中点的点——我们定义中点指的是这棵树直径的半径点位置,显然这个中点不一定在顶点上,也可能在边上,那么这个最靠近中点的点有这样一个性质:

  • 树的直径两端点到该点的最大值最小。

这个结论在IOI2013_dreaming也有体现。那么新的直径的最小值即为:

Dmin=max{ DA,DB,DA2+DB
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值