最短路程
最短路程
给定一个 个节点的树。
节点编号为 。
树中所有边均为双向边,且长度均已知。
你需要从 号点出发,沿着一条路径遍历树中所有点,路径中可以包含重复的点和边。
要求,你的行程总长度应尽可能短。
请你计算,你所需的行程总长度的最小可能值。
注意,你可以在任意点结束你的行程。
输入格式
第一行包含整数 。
接下来 行,每行包含三个整数 ,表示点 和点 之间存在一条双向边,长度为 。
输出格式
一个整数,表示行程总长度的最小可能值。
数据范围
前 个测试点满足 。
所有测试点满足 ,,。
输入样例1:
3 1 2 3 2 3 4
输出样例1:
7
输入样例2:
3 1 2 3 1 3 3
输出样例2:
9
解题思路
从根节点开始走,最后必然会停在某个点上,当递归遍历到这个终点时,回溯的时候必然是沿着根节点到终点的路径回去。可以发现,从根节点到终点这条路径的每一条边都只用走一次,到达终点时虽然要回溯当从终点回溯到根节点的路径权值是不用累加的,而从根节点到其他结点回溯时需要把回溯过程中经过的路径权值累加。因此整个路径长度是由终点决定的,整个路径长度就是所有边的权值的两倍减去从起点到终点这条路径上的长度。由于所有边的权值的两倍是一个定值,因此要让整个路径长度最小,就要让从起点到终点这条路径上的长度最大。因此要求从根节点出发的最长路径。
AC代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 const int N = 1e5 + 10, M = N * 2; 7 8 int head[N], e[M], wts[M], ne[M], idx; 9 10 void add(int v, int w, int wt) { 11 e[idx] = w, wts[idx] = wt, ne[idx] = head[v], head[v] = idx++; 12 } 13 14 int dfs(int u, int pre) { 15 int maxd = 0; 16 for (int i = head[u]; i != -1; i = ne[i]) { 17 if (e[i] != pre) maxd = max(maxd, dfs(e[i], u) + wts[i]); 18 } 19 return maxd; 20 } 21 22 int main() { 23 int n; 24 scanf("%d", &n); 25 memset(head, -1, sizeof(head)); 26 LL s = 0; 27 for (int i = 0; i < n - 1; i++) { 28 int v, w, wt; 29 scanf("%d %d %d", &v, &w, &wt); 30 add(v, w, wt), add(w, v, wt); 31 s += wt << 1; 32 } 33 printf("%lld", s - dfs(1, -1)); 34 35 return 0; 36 }
参考资料
AcWing 4706. 最短路程(AcWing杯 - 周赛):https://www.acwing.com/video/4499/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/16795649.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效