LCA应用求最短路
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=40005;
int T,n,m,ans,tot;
struct node{
int to,next,w;
}edge[N<<1];
int head[N],dep[N];
int f[N][30],dis[N][30];
void init(){
tot=0;
memset(edge,0,sizeof(edge));
memset(head,-1,sizeof(head));
memset(dep,0,sizeof(dep));
memset(dis,0,sizeof(dis));
}
void add(int u,int v,int w){
edge[tot].to=v;
edge[tot].next=head[u];
edge[tot].w=w;
head[u]=tot++;
}
void dfs(int u,int fa){
f[u][0]=fa; dep[u]=dep[fa]+1;
for(int j=1;(1<<j)<=dep[u];j++){
f[u][j]=f[f[u][j-1]][j-1];
dis[u][j]=dis[u][j-1]+dis[f[u][j-1]][j-1];
}
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].to;
if(v!=fa){
dis[v][0]=edge[i].w;
dfs(v,u);
}
}
}
int lca(int u,int v){
if(dep[u]<dep[v]) swap(u,v);
if(dep[u]!=dep[v]){
for(int j=20;j>=0;j--){
if(dep[f[u][j]]>=dep[v]){
ans+=dis[u][j];
u=f[u][j];
}
}
}
if(u==v) return ans;
for(int j=20;j>=0;j--){
if(f[u][j]!=f[v][j]){
ans+=dis[u][j];
ans+=dis[v][j];
u=f[u][j];
v=f[v][j];
}
}
return ans+dis[u][0]+dis[v][0];
}
int main(){
scanf("%d",&T);
while(T--){
init();
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z); add(y,x,z);
}
dfs(1,0);
for(int i=1;i<=m;i++){
ans=0;
int x,y;
scanf("%d%d",&x,&y);
printf("%d
",lca(x,y));
}
}
return 0;
}