分析:
mmp出题人太垃圾了
尼玛树链剖分
O(Nlog2N)
O
(
N
l
o
g
2
N
)
的算法跑得飞快,用LCA严格
O(NlogN)
O
(
N
l
o
g
N
)
的最后一个点却被卡了。
就因为出题人也写的树链剖分!所以他造的大数据就按着他不会T为标准。所以搞出来的数据用树链剖分或类似的方法都跑得飞快。
但我还是写一下只用
LCA
L
C
A
的算法吧。。。
首先,如果加速的边有贡献,其必然加速了长度最大的一条路径。
所以在最大的路径上找边权最大的边,然后答案就是:max(最大路径长-最大边权,次大路径长)
若加速的边也在次大路径中,那么答案就跟新一个:max(最大路径长-公共路径最大边权,第三大路径长)
依次这么做下去,直到相交部分为空为止。
路径求交可以用lca水过去。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 300010
using namespace std;
void Read(int &x){
x=0;
char c;
while(c=getchar(),c!=EOF&&(c<'0'||c>'9'))
continue;
x=c-'0';
while(c=getchar(),c!=EOF&&c>='0'&&c<='9')
x=x*10+c-'0';
}
int n,m;
int fa[MAXN][20],deep[MAXN],len[MAXN][20],maxl[MAXN][20];
int val[MAXN],dist[MAXN];
int head[MAXN],nxt[MAXN*2],vax[MAXN*2],px[MAXN*2],cnt;
void add_edge(int x,int y,int va){
cnt++;
nxt[cnt]=head[x];
px[cnt]=y;
vax[cnt]=va;
head[x]=cnt;
}
struct node{
int u,v,val,lcax;
bool operator < (const node &a)const{
return val<a.val;
}
}p[MAXN];
void dfs(int x,int f){
for(int i=1;i<19&&fa[x][i-1];i++){
fa[x][i]=fa[fa[x][i-1]][i-1];
maxl[x][i]=max(maxl[x][i-1],maxl[fa[x][i-1]][i-1]);
}
deep[x]=deep[f]+1;
for(int i=head[x];i;i=nxt[i]){
int u=px[i];
if(u==f)
continue;
fa[u][0]=x;
maxl[u][0]=vax[i];
dist[u]=dist[x]+vax[i];
dfs(u,x);
}
}
int quem(int u,int v){
if(deep[u]<deep[v])
swap(u,v);
int res=0;
for(int i=18;i>=0;i--)
if(deep[fa[u][i]]>=deep[v]){
res=max(res,maxl[u][i]);
u=fa[u][i];
}
if(u==v)
return res;
for(int i=18;i>=0;i--)
if(fa[u][i]!=fa[v][i]){
res=max(res,maxl[u][i]);
res=max(res,maxl[v][i]);
u=fa[u][i];
v=fa[v][i];
}
return max(res,max(maxl[u][0],maxl[v][0]));
}
inline int lca(int u,int v){
if(deep[u]<deep[v])
swap(u,v);
int res=0;
for(int i=18;i>=0;i--)
if(deep[fa[u][i]]>=deep[v])
u=fa[u][i];
if(u==v)
return u;
for(int i=18;i>=0;i--)
if(fa[u][i]!=fa[v][i]){
u=fa[u][i];
v=fa[v][i];
}
return fa[u][0];
}
int lower(int x,int y){
if(deep[x]<deep[y])
return y;
return x;
}
pair<int,int> get_inter(int pp2,int pp1,int x,int y,int u,int v){
int p1=lca(u,x),p2=lca(u,y);
int p3=lca(v,x),p4=lca(v,y);
pp1=lower(pp1,pp2);
int A=lower(p1,p2);
int B=lower(p3,p4);
if(deep[A]<deep[pp1]&&deep[B]<deep[pp1])
return make_pair(-1,-1);
if(deep[A]<deep[pp1])
A=pp1;
if(deep[B]<deep[pp1])
B=pp1;
return make_pair(A,B);
}
int main(){
Read(n),Read(m);
int u,v,va;
for(int i=1;i<n;i++){
Read(u),Read(v),Read(va);
add_edge(u,v,va);
add_edge(v,u,va);
}
dfs(1,0);
int maxv=0;
for(int i=1;i<=m;i++){
Read(p[i].u),Read(p[i].v);
p[i].lcax=lca(p[i].u,p[i].v);
p[i].val=dist[p[i].u]+dist[p[i].v]-(dist[p[i].lcax]<<1);
}
sort(p+1,p+1+m);
maxv=max(maxv,p[m].val);
pair<int,int> res=make_pair(p[m].u,p[m].v);
int ans=max(p[m-1].val,maxv-quem(res.first,res.second));
for(int i=m-1;i>=1;i--){
res=get_inter(p[i].lcax,lca(res.first,res.second),res.first,res.second,p[i].u,p[i].v);
if(res.first==res.second)
break;
ans=min(ans,max(p[i-1].val,maxv-quem(res.first,res.second)));
if(maxv-quem(res.first,res.second)>p[i-1].val)
break;
}
PF("%d",ans);
}