#include<bits/stdc++.h>
#define db 0
using namespace std;
const int MAXM=3e8+5;
const int MAXN=3e5+5;
const int MAXP=20;
int n,m;
struct node{int v,t;};
vector<node>eg[MAXN];
int deep[MAXN],s[MAXN];
int a[MAXN*2],cnt;
int st[MAXN*2][MAXP];
struct line{
int u,v;
int lca,t;
}lines[MAXN];
void DFS(int x,int fa){
a[++cnt]=x;
s[x]=cnt;
for(auto to:eg[x]){
if(to.v==fa)continue;
deep[to.v]=deep[x]+to.t;
DFS(to.v,x);
a[++cnt]=x;
}
}
int min_deep(int x,int y){
return deep[x]<deep[y]?x:y;
}
void buildST(){
for(int i=1;i<=cnt;i++)st[i][0]=a[i];
for(int j=1;(1<<j)<=cnt;j++){
for(int i=1;i+(1<<j)-1<=cnt;i++){
st[i][j]=min_deep(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
}
}
int LCA(int a,int b){
int l=s[a],r=s[b];
if(l>r)swap(l,r);
int k=(int)(log(r-l+1)/log(2));
return min_deep(st[l][k],st[r-(1<<k)+1][k]);
}
int acc[MAXN],dif[MAXN],q[MAXN],maxdel,overcot;
void check_dfs(int x,int fa){
acc[x]+=dif[x];
for(auto to:eg[x]){
if(to.v==fa)continue;
check_dfs(to.v,x);
acc[x]+=acc[to.v];
if(acc[to.v]==overcot){
maxdel=max(maxdel,to.t);
}
}
}
bool check(int k){
memset(acc,0,sizeof(acc));
memset(dif,0,sizeof(dif));
memset(q,0,sizeof(q));
maxdel=0;
overcot=0;
int st=0,ed=0;
for(int i=1;i<=m;i++){
if(lines[i].t>k){
dif[lines[i].u]++;
dif[lines[i].v]++;
dif[lines[i].lca]-=2;
q[ed++]=i;
overcot++;
}
}
//cout<<"check_is_ok\n";
check_dfs(1,0);
//cout<<"check_dfs_is_ok\n";
while(st<=ed){
if(lines[q[st++]].t-maxdel>k){
return 0;
}
}
return 1;
}
int main(){
cin>>n>>m;
for(int i=1;i<n;i++){
int a,b,t;
cin>>a>>b>>t;
eg[a].push_back({b,t});
eg[b].push_back({a,t});
}
DFS(1,0);
if(db){
for(int i=1;i<=cnt;i++)cout<<a[i]<<" ";
cout<<"\n";
for(int i=1;i<=n;i++)cout<<s[i]<<" ";
cout<<"\n";
for(int i=1;i<=n;i++)cout<<deep[i]<<" ";
cout<<"\n";
}
buildST();
if(db){
for(int j=0;(1<<j)<=cnt;j++){
for(int i=1;i+(1<<j)-1<=cnt;i++){
cout<<st[i][j]<<" ";
}
cout<<'\n';
}
}
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
lines[i].u=u;
lines[i].v=v;
lines[i].lca=LCA(u,v);
lines[i].t=deep[u]+deep[v]-2*(deep[lines[i].lca]);
}
if(db){
for(int i=1;i<=m;i++){
cout<<lines[i].u<<" ";
cout<<lines[i].v<<" ";
cout<<lines[i].lca<<" ";
cout<<lines[i].t<<'\n';
}
}
int l=0,r=MAXM;
while(l<r){
int mid=(l+r)>>1;
if(check(mid))r=mid;
else l=mid+1;
}
//cout<<"ef_ok\n";
cout<<r<<endl;
return 0;
}
预估的时间复杂度 O(nlogn+m)
但是 m 的常数会很大。