4731: 【GESP2509六级】货物运输

内存限制:512 MB 时间限制:1.000 S
评测方式:文本比较 命题人:
提交:2 解决:2

题目描述

样例输入 复制

4
1 2 6
1 3 1
3 4 5

样例输出 复制

18

提示

#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
const int N = 1e5 + 5;
int n;
vector < vector < pair < int, int >>> e;
long long s, mx;
void dfs(int u, int f, long long d) {
    mx = max(d, mx);
    for (auto p: e[ u ]) {
        if (p.first != f) {
            dfs(p.first, u , d + p.second);
        }
    }
}
int main() {
    scanf("%d", & n);
    e.resize(n + 1);
    for (int i = 1; i < n; i++) {
        int u, v, w;
        scanf("%d%d%d", & u, & v, & w);
        e[ u ].emplace_back(make_pair(v, w));
        e[ v ].emplace_back(make_pair(u, w));
        s += w;
    }
    dfs(1, 0, 0);
    printf("%lld\n", s * 2 - mx);
    return 0;
}


/*
 * 试题名称:货物运输
 * 题目大意:给定一棵n个结点的树,首都为1号结点。车队从首都出发,必须访问全部城市,可以重复走道路,最后不用返回首都。
 * 求走过道路的最小总长度。
 *
 * 算法思路:
 * 1. 遍历整棵树并且返回起点,每条边都要来回走两次,总代价 = 所有边权之和 * 2
 * 2. 不需要返回起点,可以选择距离首都最远的那条路径,不用折返回来,直接省去这一段返程
 * 3. 最终答案 = 全部边权总和 * 2 − 首都(1)出发能到达的最远距离
 *
 * 实现:使用BFS迭代遍历,避免递归DFS在n=1e5时栈溢出
 */
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

const int MAXN = 100005;

vector<pair<int, long long>> adj[MAXN]; // adj[ u ] 邻接表:(邻接点,边长度)
long long dist[MAXN];   // dist[x]:1号点到x点的距离

int main()
{
    int n;
    scanf("%d", &n);

    long long sum_edge = 0;
    // 读入n‑1条双向边
    for(int i = 1; i <= n - 1; ++i)
    {
        int u, v;
        long long l;
        scanf("%d %d %lld", &u, &v, &l);
        adj[ u ].emplace_back(v, l);
        adj[ v ].emplace_back(u, l);
        sum_edge += l;
    }

    // BFS求1到每个点距离
    queue<int> q;
    for(int i = 1; i <= n; i++) dist[i] = -1; //‑1标记未访问
    dist[1] = 0;
    q.push(1);

    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        for(auto &edge : adj[ u ])
        {
            int v = edge.first;
            long long w = edge.second;
            if(dist[ v ] == -1)
            {
                dist[ v ] = dist[ u ] + w;
                q.push(v);
            }
        }
    }

    // 找1号点出发最远的距离
    long long max_dist = 0;
    for(int i = 1; i <= n; ++i)
    {
        max_dist = max(max_dist, dist[i]);
    }

    long long answer = sum_edge * 2 - max_dist;
    printf("%lld\n", answer);
    return 0;
}