After the real system did the difference on the tree again, I found that the problem was not so difficult emmmm.
It can be seen from the problem that this is a tree, so when the preprocessing is doubled, the length of the chain is processed by the way.
Then, from the maximum value and the minimum value, we can get the time when the dichotomy is done.
Do something in the check function (I don't want to write...) look at the code.
/* id:lxyyyy Tree difference noip2015 transportation plan edge difference */ #include<iostream> #include<cstdio> #include<queue> #include<cstring> #include<cmath> #include<stack> #include<algorithm> using namespace std; #define ll long long #define rg register #define lson o<<1 #define rson o<<1|1 const int N=300000+5,M=200000+5,inf=0x3f3f3f3f,P=19650827; int n,m,cnt[N],ans=0,l=0,r=0; int f[N][25],dep[N],dis[N],bval[N]; template <class t>void rd(t &x){ x=0;int w=0;char ch=0; while(!isdigit(ch)) w|=ch=='-',ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); x=w?-x:x; } int head[N],tot=0; struct edge{int v,nxt,w;}e[N<<1]; void add(int u,int v,int w){ e[++tot]=(edge){v,head[u],w};head[u]=tot; } void dfs(int u,int fa,int w){ dep[u]=dep[fa]+1; f[u][0]=fa,bval[u]=w; for(rg int i=1;i<=20;++i){ if(dep[u]<(1<<i)) break; f[u][i]=f[f[u][i-1]][i-1]; } for(int i=head[u];i;i=e[i].nxt){ if(e[i].v==fa) continue; dis[e[i].v]=dis[u]+e[i].w,r+=e[i].w; dfs(e[i].v,u,e[i].w); } } int LCA(int a,int b){ if(dep[a]>dep[b]) swap(a,b); for(rg int i=20;i>=0;--i){ if(dep[f[b][i]]<dep[a]) continue; b=f[b][i]; } if(b==a) return a; for(rg int i=20;i>=0;--i){ if(f[a][i]==f[b][i]) continue; a=f[a][i],b=f[b][i]; } return f[a][0]; } void dfs2(int u,int fa){ for(int i=head[u];i;i=e[i].nxt){ if(e[i].v==fa) continue; dfs2(e[i].v,u); cnt[u]+=cnt[e[i].v]; } } struct node{int s,t,dis,lca;}query[N]; bool check(int x){ int tot=0,mxl=0,nw=inf; memset(cnt,0,sizeof(cnt)); for(int i=1;i<=m;++i){ if(query[i].dis<=x) continue; ++cnt[query[i].s],++cnt[query[i].t],cnt[query[i].lca]-=2; ++tot,mxl=max(mxl,query[i].dis); } dfs2(1,0); for(int i=1;i<=n;++i) if(cnt[i]==tot) nw=min(nw,mxl-bval[i]); return nw<=x; } int main(){ freopen("transport3.in","r",stdin); rd(n),rd(m); for(int i=1,u,v,w;i<n;++i) rd(u),rd(v),rd(w),add(u,v,w),add(v,u,w); dfs(1,0,0); for(int i=1;i<=m;++i){ rd(query[i].s),rd(query[i].t); query[i].lca=LCA(query[i].s,query[i].t); query[i].dis=dis[query[i].s]+dis[query[i].t]-2*dis[query[i].lca]; } while(l<r){ int mid=(l+r)>>1; if(check(mid)) r=mid; else l=mid+1; } printf("%d",l); return 0; }