HDU #2586. how far away

本文介绍了一种使用LCA算法求解树上两点间距离的方法,通过预处理得到每个节点到根节点的距离和最近公共祖先,实现快速查询。适用于需要频繁查询树上两点距离的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意

求树上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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值