1. 程式人生 > >hdu2586 LCA 離線演算法

hdu2586 LCA 離線演算法

#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]); } }