把二分放在点分治内会减小常数.
/* I will wait for you */ #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<algorithm> #include<iostream> #include<fstream> #include<vector> #include<queue> #include<deque> #include<set> #include<map> #include<string> #define make(a,b) make_pair(a,b) #define fi first #define se second using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII; const int maxn=1000010; const int maxm=1000010; const int maxs=26; const int INF=1<<29; const int P=1000000007; const double error=1e-4; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0') f=(c=='-'?-1:1),c=getchar(); while(c<='9'&&c>='0') (x*=10)+=c-'0',c=getchar(); return x*f; } struct edge{ int v,next;double w; }e[maxn]; int n,cnt,sum,root,L,R,maxp,maxP,maxj; int head[maxn],size[maxn],su[maxn],del[maxn],deep[maxn],q[maxn]; double mid,ans,a[maxn],b[maxn],val[maxn]; void insert(int u,int v,int w) { e[cnt]=(edge){v,head[u],(double)w},head[u]=cnt++; e[cnt]=(edge){u,head[v],(double)w},head[v]=cnt++; } void find(int u,int p) { size[u]=1,su[u]=0; for(int i=head[u],v;i!=-1;i=e[i].next) if(!del[v=e[i].v]&&v!=p) find(v,u),size[u]+=size[v],su[u]=max(su[u],size[v]); su[u]=max(su[u],sum-size[u]); if(su[u]<su[root]) root=u; } void work(int u,int p) { maxP=max(maxP,deep[u]),size[u]=1; for(int i=head[u],v;i!=-1;i=e[i].next) if(!del[v=e[i].v]&&v!=p) deep[v]=deep[u]+1,work(v,u),size[u]+=size[v]; } void dfs(int u,int p) { maxp=max(maxp,deep[u]); a[deep[u]]=max(a[deep[u]],val[u]); for(int i=head[u],v;i!=-1;i=e[i].next) if(!del[v=e[i].v]&&v!=p) val[v]=val[u]+(e[i].w-mid),dfs(v,u); } void slove(int u) { del[u]=1,deep[u]=0,maxP=0,work(u,0); double l=ans,r=1e6,tmp; while(r-l>error) { mid=(l+r)/2,tmp=-INF,maxj=0; b[0]=0;for(int i=1;i<=maxP;i++) b[i]=-INF; for(int i=head[u],v;i!=-1;i=e[i].next) if(!del[v=e[i].v]) { a[0]=0;for(int j=1;j<=maxP;j++) a[j]=-INF; maxp=0,val[v]=e[i].w-mid,dfs(v,0); for(int j=max(1,L-maxP),he=1,ta=0;j<=min(maxp,R);j++) { while(he<=ta&&q[he]>R-j) he++; if(L-j>=0) { while(he<=ta&&b[q[ta]]<=b[L-j]) ta--; q[++ta]=L-j; } tmp=max(tmp,b[q[he]]+a[j]); } for(int j=1;j<=maxP;j++) b[j]=max(b[j],a[j]); } tmp>0?l=mid:r=mid; } ans=max(ans,l); for(int i=head[u],v;i!=-1;i=e[i].next) if(!del[v=e[i].v]) sum=size[v],root=0,find(v,0),slove(root); } int main() { n=read(),L=read(),R=read(); memset(head,-1,sizeof(head)); for(int i=1,u,v,w;i<n;i++) u=read(),v=read(),w=read(),insert(u,v,w); root=0,sum=su[0]=n,find(1,0);slove(root); printf("%.3lf\n",ans); return 0; }