这是蒟蒻用过为数不多的multiset RE60pts 大概率是erase的时候出错了
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
int n,m;
int h[N],ne[N*2],enter[N*2],edge[N*2],idx;
int cnt;
int mx;
bool f[N];
void link(int u,int v,int w)
{
ne[idx]=h[u];
edge[idx]=w;
enter[idx]=v;
h[u]=idx++;
}
multiset<int> lian[N] ;
int dfs(int pos,int fa,int mid) //处理子链 优先组成m的链 带回不能组成m的最长链
{
lian[pos].clear();
for(int i=h[pos];~i;i=ne[i])//便利所有的边
{
int y=enter[i];
if(y==fa) continue;
int res=dfs(y,pos,mid)+edge[i];//带上来的链
if(res>=mid) { cnt++; continue ; }
lian[pos].insert( res ) ; //链数+1
}
auto it = lian[pos].begin();
bool f = 0 ;
while( !lian[pos].empty() && lian[pos].size()>1 )
{
int min_lian=*it;
while( min_lian + *lian[pos].lower_bound(mid-min_lian) < mid )
{
++it ;
min_lian = * it ;
if( it == lian[pos].lower_bound(mid-min_lian) || lian[pos].lower_bound(mid-min_lian) == lian[pos].begin() ) f = 1 ;
if( f ) break ;
}
if( f ) break ;
auto b = it ;
lian[pos].erase(b);
lian[pos].erase( lian[pos].lower_bound(mid-min_lian) );
cnt++;
}
if( !lian[pos].empty() ) return *prev(lian[pos].end());
else return 0;
}
bool check(int mid)
{
dfs(1,0,mid);
return cnt>=m;
}
signed main()
{
memset(h,-1,sizeof h);
scanf("%lld%lld",&n,&m);
for(int i=1;i<n;i++)
{
int u,v,w;
scanf("%lld%lld%lld",&u,&v,&w);
link(u,v,w); link(v,u,w);
mx+=w;
}
int l=0,r=mx;
while(l<=r)//二分最小值
{
cnt=0;
int mid=(l+r)>>1;
if( check(mid) ) l=mid+1;
else r=mid-1;
}
printf("%lld",l-1);
}
玄关awa