㊗️:☀️☃️☃️☃️☀️ • 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;
}
评论:
请先登录,才能进行评论