There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this “How far is it if I want to go from house A to house B”? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path(“simple” means you can’t visit a place twice) between every two houses. Yout task is to answer all these curious people.
Input
First line is a single integer T(T<=10), indicating the number of test cases.
For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n.
Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.
Output
For each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.
Sample Input
2
3 2
1 2 10
3 1 15
1 2
2 3
2 2
1 2 100
1 2
2 1
Sample Output
10
25
100
100
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<vector>
#include<cmath>
#define LL long long
#define mem(a, b) memset(a, b, sizeof(a))
#define N 50010
#define MOD
using namespace std;
int f[N][20], d[N], dist[N];
int ver[2*N], Next[N*2], edge[N*2], head[N];
int T, n, m, tot, t;
queue<int> q;
void add(int x, int y, int z) {//鄰接表
ver[++tot]=y, edge[tot]=z, Next[tot]=head[x], head[x]=tot;
}
void bfs() {
q.push(1), d[1]=1;
while(q.size()) {
int x=q.front();
q.pop();
for(int i=head[x]; i; i=Next[i]) {
int y=ver[i];
if(d[y]) continue;
d[y]=d[x]+1;//y是x的子節點,深度比x大1
dist[y]=dist[x]+edge[i]; //求出x,y之間的距離
f[y][0]=x;//記錄y的父節點是x
for(int j=1; j<=t; j++)
f[y][j]=f[f[y][j-1]][j-1];//記錄從x向根節點走2^j步到達的節點
q.push(y); //如果不存在該節點了,就是它的父節點
}
}
}
int lca(int x, int y) {
if(d[x]>d[y]) swap(x, y); //使得y的深度>=x的深度
for(int i=t; i>=0; i--)
if(d[f[y][i]]>=d[x]) y=f[y][i];//如果往上走後,y的深度還是比x大,則更新y
if(x==y) return x;//如果y==x,說明LCA==x
for(int i=t; i>=0; i--){ //在之前的更新後,x,y的深度一定是相同了的,這個時候同時向上更新x,y
if(f[x][i]!=f[y][i])//如果x,y的父節點不同,則更新
x=f[x][i], y=f[y][i];
else
return f[x][0];//相同了,找到共同的父節點
}
}
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d%d",&n, &m);
t=(int)(log(n)/log(2))+1;
for(int i=1; i<=n; i++) head[i]=d[i]=0;
tot=0;
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);
}
bfs();
for(int i=1; i<=m; i++) {
int x, y;
scanf("%d%d",&x, &y);
printf("%d\n",dist[x]+dist[y]-2*dist[lca(x, y)]);
}//x,y到根節點的距離減去兩倍的最近公共祖先到根節點的距離就是x,y之間最近的距離
}
}