一开始看这个题就是图嘛,但是考虑到多次询问最短路的复杂度,最短路的算法肯定是不可行的。
然后就是树剖了。。。
https://vjudge.net/contest/281481#problem/B
#include <bits/stdc++.h>
using namespace std;
#define res register int
const int maxn=4*1e4+10;
int fa[maxn],son[maxn],size[maxn],bl[maxn],h1[maxn],h2[maxn],head[maxn];
int ans=1;
struct edge{
int to,next,val;
}e[maxn*4];
void add(int x,int y,int val){
e[ans].val=val;
e[ans].to=y;
e[ans].next=head[x];
head[x]=ans++;
}
void dfs1(int x)
{
size[x]=1,son[x]=0;
for(int i=head[x];i;i=e[i].next){
if(fa[x]!=e[i].to){
h1[e[i].to]=h1[x]+1;
h2[e[i].to]=h2[x]+e[i].val;
fa[e[i].to]=x;
dfs1(e[i].to);
size[x]+=size[e[i].to];
if(size[e[i].to]>size[son[x]]) son[x]=e[i].to;
}
}
}
void dfs2(int x,int num)
{
bl[x]=num;
if(son[x]) dfs2(son[x],num);
for(int i=head[x];i;i=e[i].next){
if(e[i].to!=fa[x]&&e[i].to!=son[x]){
dfs2(e[i].to,e[i].to);
}
}
}
int lca(int x,int y)
{
int sum=0;
while(bl[x]!=bl[y]){
if(h1[bl[x]]>h1[bl[y]]){
sum+=abs(h2[bl[x]]-h2[x]);
sum+=abs(h2[fa[bl[x]]]-h2[bl[x]]);
x=fa[bl[x]];
}else{
sum+=abs(h2[bl[y]]-h2[y]);
sum+=abs(h2[fa[bl[y]]]-h2[bl[y]]);
y=fa[bl[y]];
}
}
sum+=abs(h2[x]-h2[y]);
return sum;
}
int main()
{
int T,N,M;
scanf("%d",&T);
while(T--){
scanf("%d%d",&N,&M);
ans=1;
memset(fa,0,sizeof(fa));
memset(son,0,sizeof(son));
memset(size,0,sizeof(size));
memset(bl,0,sizeof(bl));
memset(head,0,sizeof(head));
int from,to,val;
for(int i=0;i<N-1;i++){
scanf("%d%d%d",&from,&to,&val);
add(from,to,val);
add(to,from,val);
}
fa[1]=1;
dfs1(1);
dfs2(2,2);
for(int i=0;i<M;i++){
scanf("%d%d",&from,&to);
printf("%d\n",lca(from,to));
}
}
return 0;
}