set维护最小值贪心, 刚开始用树的直径+单调队列没调出来...
#include <iostream> #include <set> #define REP(i,a,n) for(int i=a;i<=n;++i) #define x first #define y second using namespace std; typedef pair<int,int> pii; const int N = 4e5+10, INF = 0x3f3f3f3f; int n, k; set<pii> s, g[N]; int main() { scanf("%d%d", &n, &k); REP(i,2,n) { int u, v, w; scanf("%d%d%d", &u, &v, &w); g[u].insert({v,w}); g[v].insert({u,w}); } REP(i,1,n) if (g[i].size()==1) { s.insert({g[i].begin()->y,i}); } int ans = 0; while (n>k||s.size()>2) { ans = s.begin()->x; int x = s.begin()->y; s.erase(s.begin()); int y = g[x].begin()->x; g[y].erase(g[y].lower_bound({x,0})); --n; if (g[y].size()==1) { s.insert({g[y].begin()->y+ans,y}); } } printf("%d\n", ans); }