Intact to make their own coming, 1A, can be happy
It is to spend a half hour,
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; inline int read() { int x=0;char c=getchar(); while(c<'0' || c>'9' ) c=getchar(); while(c>='0'&&c<='9' ) x=(x<<3)+(x<<1)+c-'0',c=getchar(); return x; } int n,m; const int N=3e5+3,M=3e5+3; int tot,head[N]; int ev[M<<1],enx[M<<1]; long long ew[M<<1]; void add(int u,int v,long long w) { ev [ ++ all] = v, ew [all] = w, Enx [all] = head [u] head [u] = all; ev [ ++ all] = u ew [all] = w, Enx [all] = head [v] head [v] = all; } int fa[N][20],dep[N]; long long dis[N][20]; int lca;long long length; void dfs(int rt,int f) { for(int i=1;i<20 && fa[rt][i-1] ;i++ ) dis [rt] [i] = dis [fa [rt] [i- 1 ]] [i- 1 ] + dis [rt] [i- 1 ] four [rt] [c] = four [four [rt] [p 1 ]] [p 1 ]; for(int i=head[rt];i;i=enx[i]) if(ev[i]!=f ) { fa [[i]] [ 0 ] = rt, dep [[i]] = dep [rt] + 1 , dis [[i]] [ 0 ] = [i]; dfs(ev[i],rt); } } void LCA(int u,int v) { length=0; if(dep[u]<dep[v] ) swap(u,v); int dist=dep[u]-dep[v]; for(int i=1,j=0;i<=dist;i<<=1,j++) if(dist&i ) length+=dis[u][j],u=fa[u][j]; if(u==v ) { lca=u; return ; } for(int i=19;i>=0;i--) if(fa[u][i]!=fa[v][i] ) length+=dis[u][i]+dis[v][i], e = four [u] [c], v = four [v] [c]; length+=dis[u][0]+dis[v][0],lca=fa[u][0]; } struct node { int fr,ed,lca; long long dis; bool operator < (const node & o ) const { return dis>o.dis; } }ask[M]; long long years main_ans; bool check ( int u, int v, long long dd) { LCA(u,v); int t=lca; if(t!=v ) return false; years = max (years, dd); return true ; } int main () { n=read(),m=read(); for(int i=1;i<n;i++) { int u=read(),v=read(); long long w; scanf("%lld",&w); add(u,v,w); } dfs(1,0); for(int i=1;i<=m;i++) { ask[i].fr =read(),ask[i].ed =read(); if(dep[ask[i].fr ] < dep[ask[i].ed ] ) swap(ask[i].fr ,ask[i].ed ); LCA(ask[i].fr ,ask[i].ed ); ask[i].dis =length,ask[i].lca =lca; } sort(ask+1,ask+m+1); int pt=ask[1].lca ,mark=0; main_ans=ask[1].dis ; for(int x=ask[1].fr ;x!=pt; ) { ans=ask[1].dis -dis[x][0]; int i;long long sub=dis[x][0]; for(i=2;i<=m && ans<ask[i].dis ;i++) { if(dep[ask[i].lca ] >= dep[x] || (dep[ask[i].fr ] < dep[x] && dep[ask[i].ed ] < dep[x] ) ) { ans=max(ans,ask[i].dis ); break; } IF (DEP [ASK [I] .fr]> = DEP [X] && Check (ASK [I] .fr, X, ASK [I] .dis -sub)) Continue ; // can choose, in function update, then Continue the else IF (DEP [ASK [I] .ed]> = DEP [X] && Check (ASK [I] .ed, X, ASK [I] .dis -sub)) Continue ; the else // if You can not vote, or withdraw it { ans=ask[i].dis ; break; } } main_ans = min (years main_ans); x=fa[x][0] ; if(x==pt && !mark ) x=ask[1].ed ,mark=1; } printf("%lld\n",main_ans); return 0; }