挺智障的一个二分。。。我还写了好久QWQ,退役算啦
题解见注释。。。
/* 先对每个点记录 向子树外的最长路 和 向子树内最长路,然后二分。 二分的时候枚举链的LCA直接做就好啦。 */ #include<bits/stdc++.h> #define ll long long using namespace std; #define pb push_back const int N=100005,B=2333333; inline int read(){ int x=0; char ch=getchar(); for(;!isdigit(ch);ch=getchar()); for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x; } int to[N*2],ne[N*2],val[N*2],num,mid,d[N]; int hd[N],n,m,f[N],dn[N],dw[N],k,ans; bool flag; inline void add(int x,int y,int z){ to[++num]=y,ne[num]=hd[x],hd[x]=num,val[num]=z; } void fdfs(int x,int fa){ for(int i=hd[x];i;i=ne[i]) if(to[i]!=fa) fdfs(to[i],x),dn[x]=max(dn[x],dn[to[i]]+val[i]); } void sdfs(int x,int fa,int L){ int D=d[x],qz[D+1],hz[D+1]; dw[x]=qz[0]=hz[0]=L; for(int i=hd[x],j=0;i;i=ne[i]) if(to[i]!=fa){ j++,qz[j]=hz[j]=dn[to[i]]+val[i]; } for(int i=1;i<D;i++) qz[i]=max(qz[i],qz[i-1]); hz[D]=0; for(int i=D-1;i;i--) hz[i]=max(hz[i],hz[i+1]); for(int i=hd[x],j=0;i;i=ne[i]) if(to[i]!=fa){ j++,sdfs(to[i],x,max(qz[j-1],hz[j+1])+val[i]); } } void dfs(int x,int fa){ int M=0,C=0; for(int i=hd[x];i;i=ne[i]) if(to[i]!=fa){ dfs(to[i],x); if(dn[to[i]]+val[i]>mid){ if(!M) M=f[to[i]]; else if(!C) C=f[to[i]]; else{ M=C=k; break;} } } f[x]=C?k:M+1; flag|=(dw[x]<=mid&&M+C<k); } inline bool solve(){ memset(f,0,sizeof(f)),flag=0; dfs(1,0); return flag; } int main(){ n=read(),k=read(); for(int i=1,uu,vv,ww;i<n;i++){ uu=read(),vv=read(),ww=read(); add(uu,vv,ww),add(vv,uu,ww); d[uu]++,d[vv]++; } fdfs(1,0),d[1]++,sdfs(1,0,0); int L=0,R=1e9; while(L<=R){ mid=L+R>>1; if(solve()) ans=mid,R=mid-1; else L=mid+1; } printf("%d ",ans); return 0; }