树上距离【LCA】

>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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值