题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586
题意:给你一颗无根树,让你求树上两点的距离。
思路:以任意一点 为根节点建一颗树,然后求询问两点的,然后用表示根节点 到点 的距离那么答案就是,。
#include <bits/stdc++.h>
using namespace std;
const int N = 4e4 + 7;
int n, m, lg[N], deep[N], fa[N][20], dis[N];
#define pii pair <int, int>
vector <pii> E[N];
void dfs(int x, int fath)
{
fa[x][0] = fath;
deep[x] = deep[fath] + 1;
for(int i = 1; (1 << i) <= n; i++)
fa[x][i] = fa[fa[x][i-1]][i-1];
for(int i = 0; i < E[x].size(); i++)
{
int v = E[x][i].first;
if(v != fath)
{
dis[v] = dis[x] + E[x][i].second;
dfs(v, x);
}
}
}
int lca(int x, int y)
{
if(deep[y] > deep[x])
swap(x, y);
while(deep[x] > deep[y])
x = fa[x][lg[deep[x]-deep[y]]];
if(x == y) return x;
for(int i = lg[deep[x]]; i >= 0; i--)
if(fa[x][i] != fa[y][i])
x = fa[x][i], y = fa[y][i];
return fa[x][0];
}
int main()
{
int T; scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n, &m);
for(int i = 1; i < n; i++)
{
int u, v, w;
scanf("%d%d%d",&u, &v, &w);
E[u].push_back({v, w});
E[v].push_back({u, w});
}
lg[0] = -1;
for(int i = 1; i <= n; i++)
lg[i] = lg[i >> 1] + 1;
dfs(1, 0);
while(m--)
{
int x, y, ans;
scanf("%d%d",&x, &y);
ans = dis[x] + dis[y] - 2 * dis[lca(x, y)];
printf("%d\n",ans);
}
}
}