给定一个 n 个节点的树。
节点编号为 1∼n。
树中所有边均为双向边,且长度均已知。
你需要从 1 号点出发,沿着一条路径遍历树中所有点,路径中可以包含重复的点和边。
要求,你的行程总长度应尽可能短。
请你计算,你所需的行程总长度的最小可能值。
注意,你可以在任意点结束你的行程。
输入格式
第一行包含整数 n。
接下来 n−1 行,每行包含三个整数 x,y,w,表示点 x 和点 y 之间存在一条双向边,长度为 w。
输出格式
一个整数,表示行程总长度的最小可能值。
数据范围
前 4 个测试点满足 1≤n≤5。
所有测试点满足 1≤n≤10^5,1≤x,y≤n,0≤w≤2×10^4。
输入样例1:
3
1 2 3
2 3 4
输出样例1:
7
输入样例2:
3
1 2 3
1 3 3
输出样例2:
9
思路:题目明确说明了有n-1条边,所以我们不用去求最短路了,因为直达这个点不饶弯子的话肯定是最短的
我们可以发现,不论我们最终去哪个点,除去起点到达这个点的路径外,其他边我们都需要走两遍
所以我们的答案不就是(所有边的长度)*2-(顶点1到达某个点的距离)
我们想要我们的答案最短,那么我们减去这个边就需要最大,所以dfs求出到达每个点的路径长度,然后找出最大的那个
代码;
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e6+5;
int n;
int h[N],e[N],w[N],ne[N],cnt;
void add(int a,int b,int c) {
e[cnt]=b;
w[cnt]=c;
ne[cnt]=h[a];
h[a]=cnt++;
}
int dfs(int u,int fa) {
int res=0;
for(int i=h[u]; ~i; i=ne[i]) {
int j=e[i];
if(j==fa)//不能倒回去
continue;
res=max(res,dfs(j,u)+w[i]);
}
return res;
}
int main() {
cin>>n;
memset(h,-1,sizeof h);
ll sum=0;
for(int i=0; i<n-1; i++) {
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
sum+=c*2;
}
cout<<sum-dfs(1,-1);
return 0;
}