题解:
只会O(n log^2 n)
O(n log n)先留坑
不开long long 0 分!!!!
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=100009; const long long oo=1000000000000000LL; int n; long long c; int nn; long long k1[maxn]; int pla[maxn]; long long len[maxn]; long long l,r,mid,ans; int cntedge=0; int head[maxn]={0}; int to[maxn<<1],nex[maxn<<1],dist[maxn<<1]; void Addedge(int x,int y,int z){ nex[++cntedge]=head[x]; to[cntedge]=y; dist[cntedge]=z; head[x]=cntedge; } int vis[maxn]; int p[maxn],cntn; int lp,rp; int father[maxn]; long long d[maxn]; long long tmpd[maxn]; void Dfs0(int now,int fa){ father[now]=fa; for(int i=head[now];i;i=nex[i]){ if(to[i]==fa)continue; d[to[i]]=d[now]+dist[i]; Dfs0(to[i],now); } } void GetD(int x){ vis[x]=1; if(father[x])GetD(father[x]); p[++cntn]=x; } long long Getdist(int x,int fa){ long long ret=0; for(int i=head[x];i;i=nex[i]){ if(to[i]==fa)continue; if(vis[to[i]])continue; ret=max(ret,dist[i]+Getdist(to[i],x)); } return ret; } struct FenwickTree{ long long c[maxn]; void Addp(int x,long long val){ while(x<=nn){ c[x]=max(c[x],val); x+=(x&(-x)); } } long long Querymax(int x){ long long ret=-oo; while(x){ ret=max(ret,c[x]); x-=(x&(-x)); } return ret; } void Clea(){ for(int i=1;i<=nn;++i)c[i]=-oo; } }T[2]; int Isok(){ long long lim1=-oo,lim2=-oo,lim3=-oo,lim4=-oo; T[0].Clea();T[1].Clea(); for(int i=1;i<=cntn;++i){ int p=lower_bound(k1+1,k1+1+nn,d[i]+len[i]-mid)-k1; long long mxsum=T[0].Querymax(p-1); long long mxdelt=T[1].Querymax(p-1); lim1=max(lim1,d[i]+len[i]+mxsum+c-mid); lim2=max(lim2,-d[i]+len[i]+mxsum+c-mid); lim3=max(lim3,d[i]+len[i]+mxdelt+c-mid); lim4=max(lim4,-d[i]+len[i]+mxdelt+c-mid); T[0].Addp(pla[i],d[i]+len[i]); T[1].Addp(pla[i],-d[i]+len[i]); } int p1=1,p2=1; int fla=0; for(int i=1;i<=cntn;++i){ long long tl=max(lim1-d[i],lim2+d[i]); long long tr=min(-lim3+d[i],-lim4-d[i]); if(tl>tr)continue; while((d[p1]<tl)&&(p1<=cntn))++p1; while((d[p1-1]>=tl)&&(p1>1))--p1; while((d[p2+1]<=tr)&&(p2<cntn))++p2; while((d[p2]>tr)&&(p2>=1))--p2; if(p1<=p2){ fla=1;break; } } return fla; } void Minit(){ cntn=lp=rp=cntedge=nn=0; l=0;r=oo;ans=oo; memset(len,0,sizeof(len)); memset(head,0,sizeof(head)); memset(vis,0,sizeof(vis)); memset(p,0,sizeof(p)); memset(father,0,sizeof(father)); memset(d,0,sizeof(d)); } int main(){ scanf("%d%lld",&n,&c); while(n!=0){ Minit(); for(int i=1;i<=n-1;++i){ int x,y,z; scanf("%d%d%d",&x,&y,&z); Addedge(x,y,z); Addedge(y,x,z); } d[1]=0; Dfs0(1,0); for(int i=1;i<=n;++i){ if(d[i]>d[lp])lp=i; } d[lp]=0; Dfs0(lp,0); for(int i=1;i<=n;++i){ if(d[i]>d[rp])rp=i; } for(int i=1;i<=n;++i)tmpd[i]=d[i]; GetD(rp); for(int i=1;i<=cntn;++i)len[i]=Getdist(p[i],0); for(int i=1;i<=cntn;++i)l=max(l,len[i]); for(int i=1;i<=cntn;++i)d[i]=tmpd[p[i]]; for(int i=1;i<=cntn;++i)k1[i]=d[i]-len[i]; sort(k1+1,k1+1+cntn); nn=unique(k1+1,k1+1+cntn)-k1-1; for(int i=1;i<=cntn;++i)pla[i]=lower_bound(k1+1,k1+1+nn,d[i]-len[i])-k1; r=l*2+d[cntn]; while(l<=r){ mid=(l+r)>>1; if(Isok()){ ans=mid;r=mid-1; }else{ l=mid+1; } } cout<<ans<<endl; scanf("%d%lld",&n,&c); } return 0; }