P14076 [GESP202509 六级] 货物运输

题目描述

A 国有 nnn 座城市,依次以 1,2,…,n1,2,\ldots,n1,2,,n 编号,其中 111 号城市为首都。这 nnn 座城市由 n−1n-1n1 条双向道路连接,第 iii 条道路(1≤i<n1 \le i < n1i<n)连接编号为 ui,viu_i,v_iui,vi 的两座城市,道路长度为 lil_ili。任意两座城市间均可通过双向道路到达。

现在 A 国需要从首都向各个城市运送货物。具体来说,满载货物的车队会从首都开出,经过一座城市时将对应的货物送出,因此车队需要经过所有城市。A 国希望你设计一条路线,在从首都出发经过所有城市的前提下,最小化经过的道路长度总和。注意一座城市可以经过多次,车队最后可以不返回首都。

输入格式

第一行,一个正整数 nnn,表示 A 国的城市数量。

接下来 n−1n-1n1 行,每行三个正整数 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 81n8

对于另外 30%30\%30% 的测试点,保证仅与一条双向道路连接的城市恰有两座。

对于所有测试点,保证 1≤n≤1051 \le n \le 10^51n1051≤ui,vi≤n1 \le u_i,v_i \le n1ui,vin1≤li≤1091 \le l_i \le 10^91li109

解析

所有的道路和城市组成了一个以首都为根节点的树,如果我们从首都出发,再返回到首都,想要路径最短,那么所有的路都要走两遍,如果无需返回首都,那么可以节省从某个叶子节点到首都的路程,那么答案为所有路径和的二倍,去掉根节点到所有节点路径长的最大值即为答案,可以使用深度优先搜索找到根节点到叶节点的最长路径,详见代码:

#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;
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐