水题。
直接倍增求lca。
x到y的距离为dis[x] + dis[y] - 2 * dis[lca(x, y)]
——代码
#include <cstdio>
#include <cstring>
#include <iostream>
#define MAXN 20002 using namespace std; int n, q, cnt;
int head[MAXN], to[MAXN], next[MAXN], val[MAXN], deep[MAXN], f[MAXN][], dis[MAXN]; inline void add(int x, int y, int z)
{
to[cnt] = y;
val[cnt] = z;
next[cnt] = head[x];
head[x] = cnt++;
} inline void dfs(int u)
{
int i, v;
deep[u] = deep[f[u][]] + ;
for(i = ; f[u][i]; i++) f[u][i + ] = f[f[u][i]][i];
for(i = head[u]; i != -; i = next[i])
{
v = to[i];
if(!deep[v])
{
f[v][] = u;
dis[v] = dis[u] + val[i];
dfs(v);
}
}
} inline int lca(int x, int y)
{
int i;
if(deep[x] < deep[y]) swap(x, y);
for(i = ; i >= ; i--)
if(deep[f[x][i]] >= deep[y])
x = f[x][i];
if(x == y) return x;
for(i = ; i >= ; i--)
if(f[x][i] != f[y][i])
x = f[x][i], y = f[y][i];
return f[x][];
} int main()
{
int i, x, y, z;
scanf("%d %d", &n, &q);
memset(head, -, sizeof(head));
for(i = ; i < n; i++)
{
scanf("%d %d %d", &x, &y, &z);
add(x, y, z);
add(y, x, z);
}
deep[] = ;
dfs();
for(i = ; i <= q; i++)
{
scanf("%d %d", &x, &y);
printf("%d\n", dis[x] + dis[y] - * dis[lca(x, y)]);
}
return ;
}