CCF-GESP计算机学会等级考试2025年9月六级C++T2 货物运输
P14076 [GESP202509 六级] 货物运输
题目描述
A 国有 nnn 座城市,依次以 1,2,…,n1,2,\ldots,n1,2,…,n 编号,其中 111 号城市为首都。这 nnn 座城市由 n−1n-1n−1 条双向道路连接,第 iii 条道路(1≤i<n1 \le i < n1≤i<n)连接编号为 ui,viu_i,v_iui,vi 的两座城市,道路长度为 lil_ili。任意两座城市间均可通过双向道路到达。
现在 A 国需要从首都向各个城市运送货物。具体来说,满载货物的车队会从首都开出,经过一座城市时将对应的货物送出,因此车队需要经过所有城市。A 国希望你设计一条路线,在从首都出发经过所有城市的前提下,最小化经过的道路长度总和。注意一座城市可以经过多次,车队最后可以不返回首都。
输入格式
第一行,一个正整数 nnn,表示 A 国的城市数量。
接下来 n−1n-1n−1 行,每行三个正整数 ui,vi,liu_i,v_i,l_iui,vi,li,表示一条双向道路连接编号为 ui,viu_i,v_iui,vi 的两座城市,道路长度为 lil_ili。
输出格式
一行,一个整数,表示你设计的路线所经过的道路长度总和。
输入输出样例 #1
输入 #1
4
1 2 6
1 3 1
3 4 5
输出 #1
18
输入输出样例 #2
输入 #2
7
1 2 1
2 3 1
3 4 1
7 6 1
6 5 1
5 1 1
输出 #2
9
说明/提示
对于 30%30\%30% 的测试点,保证 1≤n≤81 \le n \le 81≤n≤8。
对于另外 30%30\%30% 的测试点,保证仅与一条双向道路连接的城市恰有两座。
对于所有测试点,保证 1≤n≤1051 \le n \le 10^51≤n≤105,1≤ui,vi≤n1 \le u_i,v_i \le n1≤ui,vi≤n,1≤li≤1091 \le l_i \le 10^91≤li≤109。
解析
所有的道路和城市组成了一个以首都为根节点的树,如果我们从首都出发,再返回到首都,想要路径最短,那么所有的路都要走两遍,如果无需返回首都,那么可以节省从某个叶子节点到首都的路程,那么答案为所有路径和的二倍,去掉根节点到所有节点路径长的最大值即为答案,可以使用深度优先搜索找到根节点到叶节点的最长路径,详见代码:
#include <bits/stdc++.h>
using namespace std;
int n;
vector <pair<int,int>> g[100005];//邻接表存树
long long mx=0;//根节点到叶节点的最长路径
long long sum=0;//所有路径和
//深搜u为当前节点,f为父节点,d为根节点到当前节点路径长
void dfs(int u,int f,long long d){
mx=max(mx,d);//取路径长最大值
for(int i=0;i<g[u].size();i++){//遍历所有子节点
int v=g[u][i].first;//子节点
if (v!=f){//不是父节点
dfs(v,u,d+g[u][i].second);//继续深搜
}
}
}
int main() {
cin>>n;
for(int i=1;i<n;i++){
int u,v,l;
cin>>u>>v>>l;
sum+=l;//求路径和
g[u].push_back({v,l});//邻接表存树
g[v].push_back({u,l});
}
dfs(1,0,0);//从根节点开始深搜
cout<<sum*2-mx;
return 0;
}
更多推荐

所有评论(0)