小机房的树
模板题
#include <cstdio>
#include <cmath>
#include <iostream>
#define MAXN 50010
using namespace std;
int n, x, y, v, m;
int deep[MAXN], now[MAXN];
bool vis[MAXN];
int f[MAXN][22], h[MAXN][22];
int ts, cnt;
struct E {
int to, nxt, vl;
} es[MAXN * 2];
int read() {
int f = 1, k = 0;
char c = getchar();
while (c < '0' || c > '9') {
if(c == '-') {
f = -1;
}
c = getchar();
}
while(c >= '0' && c <= '9') {
k = k * 10 + c - '0';
c = getchar();
}
return f * k;
}
void addedge(int a, int b, int c) {
es[++cnt].to = b;
es[cnt].nxt = now[a];
es[cnt].vl = c;
now[a] = cnt;
}
void dfs(int a) {
vis[a] = true;
for(int i = now[a]; i != 0; i = es[i].nxt) {
if(!vis[es[i].to]) {
deep[es[i].to] = deep[a] + 1;
f[es[i].to][0] = a;
h[es[i].to][0] = es[i].vl;
dfs(es[i].to);
}
}
}
void lca_init() {
for(int i = 1; i <= ts; i ++) {
for(int j = 0; j <= n - 1; j ++) {
f[j][i] = f[f[j][i - 1]][i - 1];
h[j][i] = h[j][i - 1] + h[f[j][i - 1]][i - 1];
}
}
}
int lca(int a, int b) {
int ans = 0;
if(deep[a] < deep[b]) swap(a, b); //a的深度大
for(int i = ts; i >= 0; i -- ) {
if(deep[f[a][i]] >= deep[b]) {
ans += h[a][i];
a = f[a][i];
}
}
if(a == b) return ans;
for(int i = ts; i >= 0; i -- ) {
if(f[a][i] != f[b][i]) {
ans += h[a][i];
ans += h[b][i];
a = f[a][i];
b = f[b][i];
}
}
return ans + h[a][0] + h[b][0];
}
int main() {
n = read();
for(int i = 1; i < n; i ++) {
x = read(), y = read(), v = read();
addedge(x, y, v);
addedge(y, x, v);
}
ts = (log(n) / log(2));
deep[0] = 1;
dfs(0);
lca_init();
m = read();
for(int i = 1; i <= m; i ++) {
x = read(), y = read();
printf("%d\n", lca(x, y));
}
return 0;
}