NC52867 Highway
题目
题目描述
In ICPCCamp there were n towns conveniently numbered with
connected with (n - 1) roads.
The i-th road connecting towns aia_iai and bib_ibi has length .
It is guaranteed that any two cities reach each other using only roads.
Bobo would like to build (n - 1) highways so that any two towns reach each using only highways.
Building a highway between towns x and y costs him cents,
where is the length of the shortest path between towns x and y using roads.
As Bobo is rich, he would like to find the most expensive way to build the (n - 1) highways.
输入描述
The input contains zero or more test cases and is terminated by end-of-file. For each test case:
The first line contains an integer n.
The i-th of the following (n - 1) lines contains three integers aia_iai, bib_ibi and cic_ici.
- The number of test cases does not exceed 10.
输出描述
For each test case, output an integer which denotes the result.
示例1
输入
5 1 2 2 1 3 1 2 4 2 3 5 1 5 1 2 2 1 4 1 3 4 1 4 5 2
输出
19 15
题解
知识点:DFS,树的直径。
重修 条路,使得花费和最大,每条路的花费是两端原先的最短路。
容易证明,只要以树的直径两端为道路的一端连接其他点,即可最大化花费。因此,先通过两次dfs找到树的直径端点,然后遍历每个点取距离最远的一端即可。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; template<class T> struct Graph { struct edge { int v, nxt; T w; }; int idx; vector<int> h; vector<edge> e; Graph(int n, int m) :idx(0), h(n + 1), e(m + 1) {} void clear(int n, int m) { idx = 0; h.assign(n + 1, 0); e.assign(m + 1, { 0,0,0 }); } void add(int u, int v, T w) { e[++idx] = edge{ v,h[u],w }; h[u] = idx; } }; int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n; while (cin >> n) { Graph<int> g(n, n << 1); for (int i = 2;i <= n;i++) { int u, v, w; cin >> u >> v >> w; g.add(u, v, w); g.add(v, u, w); } function<void(int, int, vector<ll> &)> dfs = [&](int u, int fa, vector<ll> &dis) { for (int i = g.h[u];i;i = g.e[i].nxt) { int v = g.e[i].v, w = g.e[i].w; if (v == fa) continue; dis[v] = dis[u] + w; dfs(v, u, dis); } }; vector<ll> dis(n + 1); dfs(1, 0, dis); int pos1 = 0; for (int i = 1;i <= n;i++) if (dis[i] > dis[pos1]) pos1 = i; vector<ll> dis1(n + 1); dfs(pos1, 0, dis1); int pos2 = 0; for (int i = 1;i <= n;i++) if (dis1[i] > dis1[pos2]) pos2 = i; vector<ll> dis2(n + 1); dfs(pos2, 0, dis2); ll ans = dis1[pos2]; for (int i = 1;i <= n;i++) { if (i == pos1 || i == pos2) continue; ans += max(dis1[i], dis2[i]); } cout << ans << '\n'; } return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/17021930.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧