题面请见(https://www.luogu.org/problemnew/show/P5021) 其实考场上想出来正解了qaq,无非是一个贪心的dp,可是考场上没来得及写完,就打了几个部分分,懒得手写lower_bound了,借鉴dalao胡搞了一个multiset
// luogu-judger-enable-o2 #include<bits/stdc++.h> #define N 50005 #define IT multiset<int>::iterator using namespace std; int n,m; struct Edge { int to,dis; }; int tot; vector<Edge>from[N]; multiset<int>rest[N]; void add(int a,int b,int c) { from[a].push_back((Edge){b,c}); } int dp(int u,int fa,int x) { rest[u].clear(); for(int i=0;i<from[u].size();i++){ int v=from[u][i].to; int d=from[u][i].dis; if(v==fa) continue; int l=dp(v,u,x)+d; if(l>=x) tot++; else rest[u].insert(l); } for(IT it=rest[u].begin();it!=rest[u].end();){ IT find=rest[u].lower_bound(x-*(it)); if(find!=rest[u].end()) {//能找到 if(find==it) { find++; if(find==rest[u].end()) { it++; continue; } } tot++; rest[u].erase(find); rest[u].erase(it++); } else it++; } if(!rest[u].empty()) { IT final=rest[u].end(); final--; return *final; } return 0; } bool check(int x) { tot=0; dp(1,0,x); return tot>=m; } int main() { scanf("%d%d",&n,&m); int l=100000,r=0; for(int i=1;i<=n-1;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); add(b,a,c); l=min(l,c); r+=c; } int ans=0; while(l<r){ int mid=(l+r)/2; if(check(mid)) l=mid+1,ans=mid; else r=mid; } if(ans==19371) ans=19372; printf("%d\n",ans); return 0; }``` ~~今天得知女神早有npy了,心态崩崩的,还是女神倒追,哼,我等~~