根据基环分类讨论讨论。。
#include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin(), (x).end() #define fio ios::sync_with_stdio(false); cin.tie(0); using namespace std; const int N = 3e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;} template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;} template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;} template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;} int n, m, pa[N]; int road[N], cntr; LL depth[N]; LL dis[N], mx[N]; int sum[N]; bool ban[N]; LL v1[N], v2[N]; LL sufmx[N]; vector<PII> G[N]; void dfs(int u, int fa) { pa[u] = fa; for(auto& e : G[u]) { if(e.se == fa) continue; depth[e.se] = depth[u] + e.fi; dfs(e.se, u); } } LL dfs2(int u, int fa, int& sum) { LL mx = dis[u]; sum++; for(auto& e : G[u]) { if(e.se == fa || ban[e.se]) continue; dis[e.se] = dis[u] + e.fi; chkmax(mx, dfs2(e.se, u, sum)); } return mx; } int main() { scanf("%d%d", &n, &m); for(int i = 1; i < n; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); G[u].push_back(mk(w, v)); G[v].push_back(mk(w, u)); } bool can = false; dfs(1, 0); int now = n; while(now) { road[++cntr] = now; now = pa[now]; } reverse(road + 1, road + 1 + cntr); for(int i = 1; i <= n; i++) ban[road[i]] = true; for(int i = 1; i <= cntr; i++) { mx[i] = dfs2(road[i], 0, sum[i]); if(sum[i] >= 3) can = true; } LL tmp = depth[n]; LL ret = INF; if(!can) { ret = 0; chkmax(ret, dis[1] + dis[n]); for(int i = 1; i <= cntr; i++) { int u = road[i]; v1[i] = depth[u] + mx[i]; v2[i] = mx[i] - depth[u]; } sufmx[cntr] = v2[cntr]; for(int i = cntr - 1; i >= 1; i--) sufmx[i] = max(v2[i], sufmx[i + 1]); for(int i = 1; i < cntr; i++) { if(sum[i] == 1 && sum[i + 1] == 1 && i + 2 <= cntr) chkmax(ret, v1[i] + sufmx[i + 2] + depth[n]); else if(sum[i] > 1 || sum[i + 1] > 1) chkmax(ret, v1[i] + sufmx[i + 1] + depth[n]); } if(cntr >= 3) { if(sum[1] >= 2) chkmax(ret, tmp - depth[road[2]] + mx[1]); if(sum[cntr] >= 2) chkmax(ret, tmp - (depth[n] - depth[road[cntr - 1]]) + mx[cntr]); } } while(m--) { int x; scanf("%d", &x); printf("%lld ", min(tmp, ret + x)); } return 0; } /* */