HDU #2586. how far away

版权声明:转载请注明出处 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;
}

猜你喜欢

转载自blog.csdn.net/qq_41593522/article/details/83993798