树上询问两节点距离
#include<bits/stdc++.h>
#define fi first
#define se second
#define log2(a) log(n)/log(2)
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" "<<b<<endl;
#define show3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl;
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<P, int> LP;
const ll inf = 1e17 + 10;
const int N = 40010 + 10;
const ll mod = 998244353;
const int base=131;
const double pi=acos(-1);
map<string, int>ml;
map<int,int> mp;
map<int,int> vi;
priority_queue<P> q;
priority_queue<P> tq;
string s;
//int b[N], vis[N], dep[N],num[5005], t, n, m, x, y, k,a[N];
//ll ex, ey, cnt, ans, sum, flag;
int fa[N][30], deep[N],n,m,t,x,y,w;
int dis[N];
struct node
{
int to, w;
};
vector<node> graph[N];
void dfs(int v)//dfs求每一子节点到根节点的距离存放到dis数组
{
deep[v]=deep[fa[v][0]]+1;
for(int i=0;fa[v][i];++i){fa[v][i+1]=fa[fa[v][i]][i];}//进行树上倍增fa[v][i]代表v向上2^i层的父节点
for(auto i:graph[v])
{
if(deep[i.to] ){continue;}
dis[i.to]=dis[v]+i.w;
fa[i.to][0]=v;
dfs(i.to);
}
return ;
}
int lca(int a,int b)
{
if(deep[a]<deep[b])swap(a,b);
int i;
for(i=20;i>=0;--i)//将a跳转到与b相同deep的父节点
{
if(deep[fa[a][i]]>=deep[b]){a=fa[a][i];}
}
if(a==b)return a;
for(i=20;i>=0;--i)//求a,b的公共节点
{
if(fa[a][i]!=fa[b][i]){a=fa[a][i];b=fa[b][i];}
}
return fa[a][0];
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>m;
while(m--)
{
cin>>n>>t;
memset(deep,0,sizeof deep);
memset(dis,0,sizeof dis);
memset(graph,0,sizeof graph);
memset(fa,0,sizeof fa);
for(int i=1;i<n;i++)
{
int w;
cin>>x>>y>>w;
graph[x].push_back(node{y,w});
graph[y].push_back(node{x,w});
}
dfs(1);
for(int i=1;i<=t;i++)
{
cin>>x>>y;
cout<<dis[x]+dis[y]-2*dis[lca(x,y)]<<endl;
}
}
}