题解:二分答案,标记长度>mid的路径,找到最长的被所有标记路径覆盖的边,如果maxpath-maxedge<=mid就符合
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=300009;
const int oo=1000000000;
int n,m;
int cntedge;
int head[maxn];
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 f[maxn][20];
int fdist[maxn];
int dep[maxn];
int d[maxn];
void Dfs(int now,int fa){
f[now][0]=fa;
dep[now]=dep[fa]+1;
for(int i=head[now];i;i=nex[i]){
if(to[i]==fa)continue;
fdist[to[i]]=dist[i];
d[to[i]]=d[now]+dist[i];
Dfs(to[i],now);
}
}
void LCAinit(){
for(int j=1;j<=19;++j){
for(int i=1;i<=n;++i){
f[i][j]=f[f[i][j-1]][j-1];
}
}
}
int Getlca(int u,int v){
if(dep[u]<dep[v])swap(u,v);
for(int j=19;j>=0;--j){
if(dep[f[u][j]]>=dep[v])u=f[u][j];
}
if(u==v)return u;
for(int j=19;j>=0;--j){
if(f[u][j]!=f[v][j]){
u=f[u][j];v=f[v][j];
}
}
return f[u][0];
}
int g[maxn];
void Dp(int x,int fa){
for(int i=head[x];i;i=nex[i]){
if(to[i]==fa)continue;
Dp(to[i],x);
g[x]+=g[to[i]];
}
}
int rx[maxn],ry[maxn],lca[maxn],rd[maxn];
int maxlength;
int l,r,mid,ans;
void minit(){
maxlength=0;
memset(d,0,sizeof(d));
memset(dep,0,sizeof(dep));
memset(f,0,sizeof(f));
memset(fdist,0,sizeof(fdist));
memset(head,0,sizeof(head));
cntedge=0;
}
int main(){
scanf("%d%d",&n,&m);
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);
}
Dfs(1,0);
LCAinit();
for(int i=1;i<=m;++i){
scanf("%d%d",&rx[i],&ry[i]);
lca[i]=Getlca(rx[i],ry[i]);
rd[i]=d[rx[i]]+d[ry[i]]-2*d[lca[i]];
maxlength=max(maxlength,rd[i]);
}
l=0;r=oo;
while(l<=r){
mid=(l+r)>>1;
memset(g,0,sizeof(g));
int invedge=0;
for(int i=1;i<=m;++i){
if(rd[i]>mid){
g[rx[i]]++;g[ry[i]]++;g[lca[i]]-=2;++invedge;
}
}
Dp(1,0);
int maxedge=0;
for(int i=2;i<=n;++i){
if(g[i]==invedge)maxedge=max(maxedge,fdist[i]);
}
if(maxlength-maxedge<=mid){
ans=mid;r=mid-1;
}else{
l=mid+1;
}
}
cout<<ans<<endl;
return 0;
}