题目描述 一个由n户人家组成的村庄,用n-1条路径连接,形成一棵树。
现在进行道路改建,先把某条边的删除,再用这条边连接其他两个点(保持长度相同)。
使得最后村庄之间仍能相互到达,且最远的两个村庄之间的距离最小。
输入 第一行一个整数n,表示村庄的个数。
接下来n-1行,每行3个整数a、b、c,表示有一条路径连接编号为a和b的村庄(编号从0开始)。
输出 输出可以使最远距离达的最小值。
对于100%的数据,n的范围[1,5000],0≤a,b≤n-1,1≤c≤10000;
一道很不错的树的题目
主要的思考点在于
如何找到树上任意一结点的最远值和如何更新答案
根据题目描述
在切断一条边后
一棵树(A)会被分成两棵树(B,C)
这时答案会有三种情况:
1.B的直径
2.C的直径
3.两棵树重新连接后形成的新的直径
我们要做的就是使3最小
设新边连接两点为a,b
这个直径的组成为len1+len2+len3
len1为a在A树上的最远距离
len2为b在B树上的最远距离
len3为被删除边的长度
先在要解决的就是如何快速地求出每个点的最远距离
这里可以使用三遍dfs
第一次找到最远点x1
第二次找到直径的另一个端点x2(同时求出每个点到x1的距离)
第三次从x2出发,求出x2到任意点的距离
ps:节点的距离最大值一定是直径两个端点的任意一点
为了使代码较为简洁可以用结构体包起来
#include<iostream>
#include<cstdio>