版权声明:转载请注明出处 https://blog.csdn.net/qq_41593522/article/details/83993798
题意
求树上2点间距离
题解
LCA
dis[u][v] = dis[root][u] + dis[root][v] - 2 * dis[root][lca]
调试记录
无
#include <cstdio>
#include <algorithm>
#include <cstring>
const int maxn = 4 * 1e4 + 5;
const int logn = 25;
using namespace std;
struct node{
int to, next, l;
}e[maxn << 1];
int head[maxn], tot;
void addedge(int u, int v, int l){
e[++tot].to = v, e[tot].next = head[u], e[tot].l = l;
head[u] = tot;
}
int f[maxn][logn + 1], dep[maxn], dis[maxn];
void dfs(int cur, int fa){
dep[cur] = dep[fa] + 1;
f[cur][0] = fa;
for (int i = 1; (1 << i) <= dep[cur]; i++)
f[cur][i] = f[f[cur][i - 1]][i - 1];
for (int i = head[cur]; i; i = e[i].next){
if (e[i].to != fa){
dis[e[i].to] = dis[cur] + e[i].l;
dfs(e[i].to, cur);
}
}
}
int LCA(int u, int v){
if (dep[u] > dep[v]) swap(u, v);
for (int i = logn; i >= 0; i--)
if (dep[u] <= dep[v] - (1 << i)) v = f[v][i];
if (u == v) return u;
for (int i = logn; i >= 0; i--)
if (f[u][i] != f[v][i]) u = f[u][i], v = f[v][i];
return f[u][0];
}
int T, n, Q;
int main(){
scanf("%d", &T);
while (T--){
memset(e, 0, sizeof e);
memset(head, 0, sizeof head);
memset(dis, 0, sizeof dis);
tot = 0;
scanf("%d%d", &n, &Q);
for (int u, v, l, i = 1; i < n; i++){
scanf("%d%d%d", &u, &v, &l);
addedge(u, v, l); addedge(v, u, l);
}
dfs(1, 0);
while (Q--){
int u, v; scanf("%d%d", &u, &v);
printf("%d\n", dis[u] + dis[v] - 2 * dis[LCA(u, v)]);
}
}
return 0;
}