hdu2586 LCA 離線演算法
阿新 • • 發佈:2019-02-13
#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#define MST(s,q) memset(s,q,sizeof(s))
#define INF 0x3f3f3f3f
#define MAXN 50005
#define Lchild id<<1
#define Rchild (id<<1)+1
using namespace std;
struct Query {
int v, no;
} tmp;
int N, M, T, F[MAXN], dis[MAXN], level[MAXN], vis[MAXN], ans[MAXN];
vector<int> node[MAXN], w[MAXN];
vector<Query> query[MAXN];
void init() {
for (int i = 0; i < MAXN; i++) {
F[i] = i;
ans[i] = dis[i] = vis[i] = 0;
level[i] = 1;
node[i].clear();
query[i].clear();
w[i].clear();
}
}
int Find (int x) {
if (F[x] == x) return x;
return F[x] = Find (F[x]);
}
void Union (int x, int y) {
int fa = Find (x), fb = Find (y);
if (fa == fb) return;
F[fb] = fa;
}
void LCA (int root, int value) {
vis[root] = 1;
dis[root] = value;
int len = node[root].size();
for (int i = 0; i < len; i++) {
int v = node[root][i];
if (vis[v]) continue;
LCA (v, value + w[root][i]); // 遞迴子樹
Union (root, v);
}
len = query[root].size();
for (int i = 0; i < len; i++) {
int v = query[root][i].v, no = query[root][i].no;
if (!vis[v]) continue;
ans[no] = dis[root] + dis[v] - 2 * dis[Find (v)];
}
}
int main() {
cin >> T;
while (T--) {
cin >> N >> M;
init();
int u, v, z;
for (int i = 1; i < N; i++) {
scanf ("%d%d%d", &u, &v, &z);
node[u].push_back (v), w[u].push_back (z);
node[v].push_back (u), w[v].push_back (z);
}
for (int i = 0; i < M; i++) {
scanf ("%d%d", &u, &v);
tmp.no = i;
tmp.v = v, query[u].push_back (tmp);
tmp.v = u, query[v].push_back (tmp);
}
LCA (1, 0);
for (int i = 0; i < M; i++)
printf ("%d\n", ans[i]);
}
}