50pts,提交记录
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define mpr make_pair
#define fr first
#define sc second
inline int read(){
int res=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') {res=res*10+(c-'0');c=getchar();}
return res*f;
}
const int N=3e5+5;
vector<pair<int,int> >e[N];
int n,k;
int sum[N];
pair<int,int>ta[N];
int dep[N],siz[N],fa[N],son[N];
int dfs(int u,int father){
dep[u]=dep[father]+1;
fa[u]=father;
siz[u]=1;
int maxn=-1;
for (auto v:e[u]){
if (v.fr==father) continue;
int sizes=dfs(v.fr,u);
siz[u]+=sizes;
if (sizes>maxn) maxn=sizes,son[u]=v.fr;
}
return siz[u];
}
int dfn[N],top[N],tip=1;
void dfs2(int u,int father,int op){
if (op==1) top[u]=top[father];
dfn[u]=tip++;
if (son[u]!=0) dfs2(son[u],u,1);
for (auto v:e[u]){
if (v.fr==father||v.fr==son[u]) continue;
dfs2(v.fr,u,0);
}
}
int va[N];
int lca(int x,int y){
if (top[x]==top[y]) return dep[x]>dep[y]?y:x;
if (dep[top[x]]<dep[top[y]]) swap(x,y);
return lca(fa[top[x]],y);
}
void isum(){
for (int i=1;i<=n;i++) sum[i]+=sum[i-1];
}
int query(int l,int r){
return sum[r]-sum[l-1];
}
void init(int root){
dfs(root,0);
for (int i=1;i<=n;i++) top[i]=i;
dfs2(root,0,0);
for (int i=1;i<=n;i++){
for (auto j:e[i]){
int u=i,v=j.fr,w=j.sc;
if (dep[u]<dep[v]) swap(u,v);
va[u]=w;
}
}
}
inline int QueryPath(int x,int y){
int res=0;
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]) swap(x,y);
res+=query(dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
if (x!=y) res+=query(dfn[son[x]],dfn[y]);
return res;
}
struct node{
int l,r,s;
}pa[N];
bool comp(node o,node p){
return o.s>p.s;
}
int g[N];
void adder(int l,int r,int z){
g[r+1]-=z;
g[l]+=z;
}
inline void AddPath(int x,int y,int z){
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]) swap(x,y);
adder(dfn[top[x]],dfn[x],z);
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
if (x!=y) adder(dfn[son[x]],dfn[y],z);
}
int lawer(int z){
int l=1,r=k;
while (l<r){
int mid=(l+r+1)>>1;
if (pa[mid].s>z) l=mid;
else r=mid-1;
}
return l;
}
signed main(){
n=read(),k=read();
for (int i=1;i<n;i++){
int u=read(),v=read(),w=read();
e[u].push_back(mpr(v,w));
e[v].push_back(mpr(u,w));
}
init(1);
for (int i=1;i<=n;i++)
sum[dfn[i]]=va[i];
isum();
for (int i=1;i<=k;i++){
pa[i].l=read();
pa[i].r=read();
pa[i].s=QueryPath(pa[i].l,pa[i].r);
}
sort(pa+1,pa+k+1,comp);
int l=pa[k].s,r=pa[1].s;
while (l<r){
int mid=(l+r)>>1;
memset(g,0,sizeof(g));
int L=1,R=lawer(mid);
for (int i=L;i<=R;i++) AddPath(pa[i].l,pa[i].r,1);
int maxn=0;
for (int i=1;i<=n;i++){
g[i]+=g[i-1];
if (g[i]==R-L+1){
maxn=max(maxn,sum[dfn[i]]-sum[dfn[i]-1]);
}
}
if (pa[1].s-maxn<=mid) r=mid;
else l=mid+1;
}
cout<<l;
return 0;
}