>Link
ybtoj树上距离
>解题思路
没什么好讲的,这就是一道LCA的模板题
(为什么先写这道题而不写开车旅行?因为我菜🤩 我最爱刷水题了!!!)
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 10010
#define LL long long
using namespace std;
struct edge
{
int to, next;
LL w;
} e[N * 2];
int n, m, h[N], cnt, dep[N], f[N][50], lg[N];
LL sum[N];
void add (int u, int v, int w)
{
e[++cnt] = (edge){v, h[u], w}; h[u] = cnt;
e[++cnt] = (edge){u, h[v], w}; h[v] = cnt;
}
void dfs (int now, int fath)
{
dep[now] = dep[fath] + 1;
f[now][0] = fath;
for (int i = 1; i <= lg[dep[now]] - 1; i++)
f[now][i] = f[f[now][i - 1]][i - 1];
for (int i = h[now]; i; i = e[i].next)
{
if (e[i].to == fath) continue;
sum[e[i].to] = sum[now] + e[i].w;
dfs (e[i].to, now);
}
}
int lca (int x, int y)
{
if (dep[x] < dep[y]) swap (x, y);
while (dep[x] > dep[y])
x = f[x][lg[dep[x] - dep[y]] - 1];
if (x == y) return x;
for (int i = lg[dep[x]] - 1; i >= 0; i--)
if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
return f[x][0];
}
int main()
{
scanf ("%d%d", &n, &m);
for (int i = 1; i < n; i++)
{
int u, v; LL w;
scanf ("%d%d%lld", &u, &v, &w);
add (u, v, w);
}
for (int i = 1; i <= n; i++)
lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
dfs (1, 0);
for (int i = 1; i <= m; i++)
{
int x, y;
scanf ("%d%d", &x, &y);
int z = lca (x, y);
printf ("%lld\n", sum[x] + sum[y] - 2 * sum[z]);
}
return 0;
}