E. Tree and Hamilton Path 2
如果题目是从一个点出发,所有点都要经过一次,并且最后要回到起点,答案就是边权和 * 2
现在不要回到起点,可以省掉一条链上的边权和,也就是找到以起点为根,到最深的叶子节点路径上的边权和。
最后的答案是 :边权和 * 2 - 树的直径
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5, INF = 1e18;
struct node
{
int v, w;
};
int T, n, cnt, ans, mxd, d[N];
vector<node> G[N];
void dfs(int u, int fa)
{
for (auto x : G[u])
{
int v = x.v, w = x.w;
if (v == fa)
continue;
dfs(v, u); // 先递归到叶子节点,再一步步退上来
mxd = max(mxd, d[u] + d[v] + w); // 更新最大直径:一条是父节点已经算好的最大子链,一条是上一步算出来的其中一个子节点的最大子链,两个相加再加上父子之间的路径长度
d[u] = max(d[u], d[v] + w); // 更新父节点的最大子链
// mxd 和 d[u] 的更新顺序不能反
}
}
signed main()
{
cin >> n;
for (int i = 1; i < n; i ++)
{
int u, v, w;
cin >> u >> v >> w;
ans += 2 * w;
G[u].push_back({v, w}), G[v].push_back({u, w});
}
dfs(1, 0);
cout << ans - mxd;
return 0;
}