给定一个 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;
- }