HDU 5286 How far away ? lca

题目链接:

题目

How far away ?
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)

问题描述

There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B"? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path("simple" means you can't visit a place twice) between every two houses. Yout task is to answer all these curious people.

输入

First line is a single integer T(T<=10), indicating the number of test cases.
For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n.
Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.

输出

For each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.

样例

input
2
3 2
1 2 10
3 1 15
1 2
2 3

2 2
1 2 100
1 2
2 1

output
10
25
100
100

题意

给你一颗树,问两点间距离

题解

离线求每个点的深度,则距离为dep[u]+dep[v]-2*dep[lca(u,v)];

代码

#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#define mp make_pair
#define X first
#define Y second
using namespace std;

const int maxn = 4e4+10;
const int maxm = 18;

int n, m;

vector<pair<int, int> > G[maxn];
int dep[maxn],dep2[maxn],anc[maxn][maxm];
void dfs(int u,int fa,int d,int d2) {
	dep[u] = d, dep2[u] = d2;
	anc[u][0] = fa;
	for (int j = 1; j < maxm; j++) {
		int f = anc[u][j - 1];
		anc[u][j] = anc[f][j - 1];
	}
	for (int i = 0; i < G[u].size(); i++) {
		int v = G[u][i].X, w = G[u][i].Y;
		if (v == fa) continue;
		dfs(v, u, d + 1, d2 + w);
	}
}

int Lca(int u, int v) {
	if (dep[u] < dep[v]) swap(u, v);
	for (int i = maxm - 1; i >= 0; i--) {
		if (dep[anc[u][i]] >= dep[v]) {
			u = anc[u][i];
		}
	}
	if (u == v) return u;
	for (int i = maxm - 1; i >= 0; i--) {
		if (anc[u][i] != anc[v][i]) {
			u = anc[u][i], v = anc[v][i];
		}
	}
	return anc[u][0];
}

void init() {
	for (int i = 0; i <= n; i++) G[i].clear();
	memset(anc, 0, sizeof(anc));
}

int main() {
	int tc;
	scanf("%d", &tc);
	while (tc--) {
		scanf("%d%d", &n, &m);
		init();
		for (int i = 0; i < n - 1; i++) {
			int u, v, w;
			scanf("%d%d%d", &u, &v, &w);
			G[u].push_back(mp(v, w));
			G[v].push_back(mp(u, w));
		}
		dfs(1, 0,0,0);
		while (m--) {
			int u, v;
			scanf("%d%d", &u, &v);
			int lca = Lca(u, v);
			printf("%d
", dep2[u] + dep2[v] - 2 * dep2[lca]);
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/fenice/p/5625455.html