学习一发高端的TarjanLCA。
注意并查集合并时必须用v的父亲与u的父亲合并。
/* Pigonometry */
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 40005, maxm = 205;
int n, m, head[maxn], cnt, fa[maxn], dis[maxn], vis[maxn], clo, ans[maxm];
struct _edge {
int v, w, next;
} g[maxn << 1];
struct _query {
int v, qid;
};
vector<_query> query[maxn];
inline int iread() {
int f = 1, x = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return f * x;
}
inline void add(int u, int v, int w) {
g[cnt] = (_edge){v, w, head[u]};
head[u] = cnt++;
}
inline int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
inline void tarjan(int x) {
vis[x] = clo;
for(int i = head[x]; ~i; i = g[i].next) if(vis[g[i].v] != clo) {
dis[g[i].v] = dis[x] + g[i].w;
tarjan(g[i].v);
fa[find(g[i].v)] = find(x);
}
for(int i = 0; i < query[x].size(); i++) if(vis[query[x][i].v] == clo) {
int v = query[x][i].v, qid = query[x][i].qid;
ans[qid] = dis[x] + dis[v] - 2 * dis[find(v)];
}
}
int main() {
for(int T = iread(); T; T--) {
n = iread(); m = iread();
for(int i = 1; i <= n; i++) head[i] = -1, fa[i] = i, query[i].clear(); cnt = 0;
for(int i = 1; i < n; i++) {
int u = iread(), v = iread(), w = iread();
add(u, v, w); add(v, u, w);
}
for(int i = 1; i <= m; i++) {
int u = iread(), v = iread();
query[u].push_back((_query){v, i});
query[v].push_back((_query){u, i});
}
clo++;
tarjan(1);
for(int i = 1; i <= m; i++) printf("%d\n", ans[i]);
}
return 0;
}