二分check部分在dfs(int x,int lst)
输出跟正解比偏小
如果可以希望给组较小的hack数据
int ans,N,M;//ans计数
int L=1,R,mid;
int zhi[MAXN];
multiset<int> s[MAXN];
multiset<int>::iterator it;
void dfs(int x,int lst)
{
for (int i=head[x],y,z;i;i=e[i].next_)
{
y=e[i].to_,z=e[i].value_;
if (y==lst) continue;
dfs(y,x);
if (zhi[y]+z>=mid) ans++;
else s[x].insert(zhi[y]+z);
}
zhi[x]=0;//先清零
while (!s[x].empty())
{
it=s[x].begin();
int xx=*it;
s[x].erase(it);//先删去最小数
if (s[x].empty()) {zhi[x]=xx;return;}//没数了直接退出
it=s[x].lower_bound(mid-xx);
if (it!=s[x].end()) continue;//当前最小数匹配失败,忽略
s[x].erase(it);
ans++;//匹配成功的操作
}
}
bool check()
{
ans=0;
dfs(1,-1);
//printf("%d:%d\n",mid,ans);
return ans>=M;
}
int Root;
void dfs0(int x,int lst,int now)
{
if (now>R) R=now,Root=x;
for (int i=head[x],y,z;i;i=e[i].next_)
{
y=e[i].to_,z=e[i].value_;
if (y==lst) continue;
dfs0(y,x,now+z);
}
}
void dfs1(int x,int lst,int now)
{
R=now>R?now:R;
for (int i=head[x],y,z;i;i=e[i].next_)
{
y=e[i].to_,z=e[i].value_;
if (y==lst) continue;
dfs0(y,x,now+z);
}
}
int main()
{
freopen("P5021_17.in","r",stdin);
//freopen("P5021_12.out","w",stdout);
read(N),read(M);
for (int i=1;i<N;i++)
{
int x,y,z;read(x),read(y),read(z);
Add(x,y,z),Add(y,x,z);
}
dfs0(1,-1,0);
dfs1(Root,-1,0);
while (L<R)
{
mid=(L+R+1)>>1;
if (check())
L=mid;
else
R=mid-1;
}
printf("%d\n",L);
return 0;
}