BZOJ4379 POI2015 Modernizacja autostrady

这篇博客探讨了在无根树中如何通过移除一条边并添加一条新边来改变树的直径,旨在最小化和最大化新树的直径。博主首先介绍了问题背景和输入输出格式,并详细阐述了求解最小直径和最大直径的思路。最小直径的求解关键是断开直径并在两部分中寻找最短直径;最大直径的求解则需要考虑断开非直径边可能导致的影响。博客中提到,最小直径可通过预处理树形DP解决,最大直径则需要枚举断点。文章最后提到了寻找距离中点最近点的方法,总结了树的直径问题的各种性质。
摘要由CSDN通过智能技术生成

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
BZOJ 2908 题目是一个数据下载任务。这个任务要求下载指定的数据文件,并统计文件中小于等于给定整数的数字个数。 为了完成这个任务,首先需要选择一个合适的网址来下载文件。我们可以使用一个网络爬虫库,如Python中的Requests库,来帮助我们完成文件下载的操作。 首先,我们需要使用Requests库中的get()方法来访问目标网址,并将目标文件下载到我们的本地计算机中。可以使用以下代码实现文件下载: ```python import requests url = '目标文件的网址' response = requests.get(url) with open('本地保存文件的路径', 'wb') as file: file.write(response.content) ``` 下载完成后,我们可以使用Python内置的open()函数打开已下载的文件,并按行读取文件内容。可以使用以下代码实现文件内容读取: ```python count = 0 with open('本地保存文件的路径', 'r') as file: for line in file: # 在这里实现对每一行数据的判断 # 如果小于等于给定整数,count 加 1 # 否则,不进行任何操作 ``` 在每一行的处理过程中,我们可以使用split()方法将一行数据分割成多个字符串,并使用int()函数将其转换为整数。然后,我们可以将该整数与给定整数进行比较,以判断是否小于等于给定整数。 最后,我们可以将统计结果打印出来,以满足题目的要求。 综上所述,以上是关于解决 BZOJ 2908 数据下载任务的简要步骤和代码实现。 希望对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值