倍增求两个点的距离
作者:
Dessa
,
2024-07-29 15:50:00
,
所有人可见
,
阅读 4
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include <random>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<fstream>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#include<bitset>
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
#define endl '\n'
#define int ll
#define PI acos(-1)
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 5e5 + 50, MOD = 998244353;
vector<int>tree[N];
int deep[N], fa[N][32], dis[N];
//存储的是边权
unordered_map<int, unordered_map<int, int>>mymap;
int lca(int x, int y)
{
if (deep[x] != deep[y])
{
if (deep[x] < deep[y])swap(x, y);
for (int i = 20; i >= 0; i--)
{
if (deep[fa[x][i]] >= deep[y])x = fa[x][i];
}
}
if (x == y)return x;
for (int i = 20; i >= 0; i--)
{
int a = fa[x][i], b = fa[y][i];
if (a != b)
{
x = a, y = b;
}
}
return fa[x][0];
}
void dfs(int x, int y)
{
fa[x][0] = y;
for (int i = 1; i < 20; i++)
{
fa[x][i] = fa[fa[x][i - 1]][i - 1];
}
for (auto& i : tree[x])
{
if (i == y)continue;
deep[i] = deep[x] + 1;
//i点到1的距离就是:父节点到1的距离+父节点到它的距离
dis[i] = dis[x] + mymap[x][i];
dfs(i, x);
}
}
void solve()
{
//因为是多组数据,所以每次要把stl清空
tree->clear();
mymap.clear();
int n, m, x, y, w;
cin >> n >> m;
for (int i = 1; i < n; i++)
{
cin >> x >> y >> w;
tree[y].push_back(x);
tree[x].push_back(y);
mymap[x][y] = w;
mymap[y][x] = w;
}
//题目没给我们root,我们设1为根
deep[1] = 1;
dfs(1, 0);
while (m--)
{
cin >> x >> y;
int z = lca(x, y);
cout << dis[x] + dis[y] - dis[z] * 2 << endl;
}
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}