题目:

小A给你了一棵树,对于这棵树上的每一条边,你都可以将它复制任意(可以为0)次(即在这条边连接的两个点之间再加一条边权相同的边),求所有可能新形成的图中欧拉路的最短长度。
欧拉路:从图中任意一个点开始到图中任意一个点结束的路径,并且图中每条边只通过恰好一次。



做法:

不难发现每条树边顶多用次,而且路径的起点和终点都是叶子。假如我们确定个叶子作为欧拉路的起终点。那么路径上的边算次,其他边算次。所以我们让这个路径最长,也就是选取树的某条直径端点作为欧拉路的两端,在直径上的边算次贡献,不在则次,就是答案。


代码:

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false), cin.tie(0)
#define debug(a) cout << #a ": " << a << endl
using namespace std;
typedef long long ll;
const int N = 2e5 + 7;
vector<pair<int,int> > g[N];
int rt1, rt2, dis[N], fa[N], mrk[N];
void dfs(int u, int p, int& rt){
    for (auto &pr : g[u]) if (pr.first != p){
        int v = pr.first, w = pr.second;
        fa[v] = u, mrk[v] = w;
        dis[v] = dis[u] + w;
        if (dis[v] > dis[rt]) rt = v;
        dfs(pr.first, u, rt);
    }
}
int main(void){
    IOS;
    int n; cin >> n;
    ll ans = 0;
    for (int i = 0; i < n-1; ++i){
        int u, v, w; cin >> u >> v >> w;
        g[u].push_back(make_pair(v, w));
        g[v].push_back(make_pair(u, w));
        ans += 2*w;
    }
    dfs(1, 0, rt1); dis[rt1] = 0; dfs(rt1, 0, rt2);
    //debug(rt1), debug(rt2);
    while (rt2 != rt1){
        ans -= mrk[rt2], rt2 = fa[rt2];
    }
    cout << ans << endl;
    return 0;
}