ans

㊗️:☀️☃️☃️☃️☀️  •  2小时前


#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
using namespace std;
struct edge {
	int to;
	int value;
};
vector<edge> map[500001];
int anc[500001][25]; //anc[i][k] 为i的2^k级祖先
long long d[500001][25]; //d[i][k] 为i到的2^k级祖先的距离
int dep[500001];
void dfs(int node, int father) {
	anc[node][0] = father;
	dep[node] = dep[father] + 1;
	for (int i = 1; anc[node][i - 1] > 0; i++) {
		anc[node][i] = anc[anc[node][i - 1]][i - 1];
		d[node][i] = d[anc[node][i - 1]][i - 1] + d[node][i - 1];
	}//node的2^i级祖先,是node的2^(i-1)级祖先的2^(i-1)级祖先
	for (edge next : map[node])if (father != next.to) {
		d[next.to][0] = next.value;
		dfs(next.to, node);
	}
}
long long getDistance(int x, int y) {
	long long ans = 0;
	if (dep[x] < dep[y]) {
		swap(x, y);
	} //交换x为较深的那个,方便操作
	for (int i = 24; dep[x] > dep[y]; i--) if (dep[anc[x][i]] >= dep[y]) {
		ans += d[x][i]; //先加再跳
		x = anc[x][i];
	}
	//如果y一开始就是x的祖先,那么此时x会跳到y上(主要是下面的anc[x][0]就是错误答案了)
	if (x == y) return ans;
	else {
		for (int i = 24; i >= 0; i--) if (anc[x][i] != anc[y][i]) {
			//一起跳,如果相同就是有可能跳过头了
			ans += d[x][i] + d[y][i]; //先加再跳
			x = anc[x][i];
			y = anc[y][i];
		}
		//最后xy一定在答案的下一层
		return ans + d[x][0] + d[y][0];
	}
}
int main() {
	int n, m;
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n - 1; i++) {
		int x, y,w;
		scanf("%d%d%d", &x, &y, &w);
		map[x].push_back({ y,w });
		map[y].push_back({ x,w });
	}
	dfs(1, 0);
	for (int i = 0; i < m; i++) {
		int x, y;
		scanf("%d%d", &x, &y);
		printf("%d\n", getDistance(x, y));
	}
	return 0;
}



评论:

请先登录,才能进行评论