题解:
先求直径,可以证明这条边一定连在直径的两个点上。
那么我们处理出每个直径往外延伸的最长距离,再结合在链上的长度,就可以很好的列出式子了。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int RLEN=1<<18|1;
inline char nc() {
static char ibuf[RLEN],*ib,*ob;
(ib==ob) && (ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob) ? -1 : *ib++;
}
inline int rd() {
char ch=nc(); int i=0,f=1;
while(!isdigit(ch)) {if(ch=='-')f=-1; ch=nc();}
while(isdigit(ch)) {i=(i<<1)+(i<<3)+ch-'0'; ch=nc();}
return i*f;
}
const int N=2e5+50;
int n,m,A,B,X,L;
int g[N],nt[N],vt[N],w[N],ec;
int fa[N],on[N],q[N],a[N],b[N];
LL mx[N],d[N],lim[4];
inline void add(int x,int y,int z) {nt[++ec]=g[x]; g[x]=ec; vt[ec]=y; w[ec]=z;}
inline bool cmp1(const int &a,const int &b) {return mx[a]+d[a]<mx[b]+d[b];}
inline bool cmp2(const int &a,const int &b) {return mx[a]-d[a]<mx[b]-d[b];}
inline void dfs(int x,int y,LL z) {
d[x]=z; fa[x]=y; if(d[x]>=d[X]) X=x;
for(int e=g[x];e;e=nt[e])
if(vt[e]!=y) dfs(vt[e],x,z+w[e]);
}
inline LL dfs2(int x,int y,LL z) {
LL mx=z;
for(int e=g[x];e;e=nt[e])
if(vt[e]!=y) mx=max(mx,dfs2(vt[e],x,z+w[e]));
return mx;
}
LL mxlen;
inline void dfs3(int x,int y,LL z) {
if(z>=mxlen) X=x;
for(int e=g[x];e;e=nt[e])
if(vt[e]!=y && !on[vt[e]]) dfs3(vt[e],x,z+w[e]);
}
struct BIT_MAX {
LL bit[N];
inline void init() {
for(int i=1;i<=n;i++) bit[i]=-1e18;
}
inline void inc(int pos,LL v) {
for(int i=pos;i;i-=(i&(-i))) bit[i]=max(bit[i],v);
}
inline LL ask(int pos,LL v=-1e18) {
for(int i=pos;i<=n;i+=(i&(-i))) v=max(v,bit[i]);
return v;
}
} bit[2];
inline bool check(LL k) {
bit[0].init(); bit[1].init();
lim[0]=lim[1]=lim[2]=lim[3]=-1e18;
int j=m;
for(int i=1;i<=m;i++) {
int u=b[i];
while(j && mx[u]-d[u]>k-mx[a[j]]-d[a[j]]) {
bit[0].inc(a[j],mx[a[j]]+d[a[j]]);
bit[1].inc(a[j],mx[a[j]]-d[a[j]]);
--j;
}
LL v0=bit[0].ask(u+1), v1=bit[1].ask(u+1);
if(v0!=-1e18 && v1!=-1e18) {
lim[0]=max(lim[0],v0+mx[u]+d[u]+L-k);
lim[1]=max(lim[1],v1+mx[u]+d[u]+L-k);
lim[2]=max(lim[2],v0+mx[u]-d[u]+L-k);
lim[3]=max(lim[3],v1+mx[u]-d[u]+L-k);
}
}
int h1=m+1, h2=0; d[h1]=1e18; d[h2]=-1e18;
for(int i=m;i>=1;i--) {
LL up=min(d[i]-lim[1],-lim[3]-d[i]);
LL low=max(lim[0]-d[i],lim[2]+d[i]);
while(h2<m && d[h2+1]<=up) ++h2;
while(h1>1 && d[h1-1]>=low) --h1;
while(h2 && d[h2]>up) --h2;
while(h1<=m && d[h1]<low) ++h1;
if(h2>=h1 && h2>=i) return true;
} return false;
}
int main() {
while((n=rd()) && (L=rd())) {
ec=0; memset(g,0,sizeof(g));
memset(on,0,sizeof(on));
memset(d,0,sizeof(d));
for(int i=1;i<n;i++) {
int x=rd(), y=rd(), z=rd();
add(x,y,z); add(y,x,z);
} dfs(1,0,0);
dfs(A=X,0,0); B=X; m=0;
for(int i=B;i;i=fa[i]) q[++m]=i, on[i]=1;
reverse(q+1,q+m+1);
memcpy(mx,d,sizeof(mx));
for(int i=1;i<=m;i++) d[i]=mx[q[i]];
memset(mx,0,sizeof(mx));
LL l=0, r=d[m], ans;
for(int i=1;i<=m;i++)
for(int e=g[q[i]];e;e=nt[e])
if(!on[vt[e]]) {
mx[i]=max(mx[i],dfs2(vt[e],q[i],w[e]));
mxlen=0; dfs3(vt[e],q[i],0);
mxlen=0; l=max(l,(dfs3(A=X,0,0),mxlen));
}
for(int i=1;i<=m;i++) a[i]=i, b[i]=i;
sort(a+1,a+m+1,cmp1);
sort(b+1,b+m+1,cmp2);
if(l>r) ans=l;
while(l<=r) {
LL mid=(l+r)>>1;
if(check(mid)) ans=mid, r=mid-1;
else l=mid+1;
} cout<<ans<<'\n';
}
}