LCA问题
LCA的求解有3种,转化为RMQ,Tarjan离线预处理,倍增法。
RMQ法:
#include <iostream> #include <string> #include <algorithm> #include <vector> #include <set> #include <cmath> #include <cstring> #define LL long long using namespace std; struct node { int p, v; }; const LL N = 100005; vector<node> g[N]; LL fst[N]; LL ver[N * 2]; LL deep[N * 2]; LL dist[N]; LL pos; int vis[N]; int n, m; LL lg2(LL nu) { return log10(nu) / log10(2); } void dfs(int now, int dep, int dis) { ver[pos] = now; fst[now] = pos; deep[pos++] = dep; dist[now] = dis; vis[now] = 1; for (int i = 0; i < g[now].size(); i++) { if (!vis[g[now][i].p]) { dfs(g[now][i].p, dep + 1, dis + g[now][i].v); ver[pos] = now; deep[pos++] = dep; } } } LL dp[N * 2][25]; LL bit[25]; void initRMQ() { int bitlen = lg2(2 * n - 1); bit[0] = 1; for (int i = 1; i <= bitlen; i++) bit[i] = bit[i - 1] * 2; for (int i = 0; i <pos; i++) dp[i][0] = ver[i]; for (int j = 1; j <= bitlen; j++) { for (int i = 0; i + bit[j] < pos; i++) { int lx = dp[i][j - 1], rx = dp[i + bit[j - 1]][j - 1]; dp[i][j] = deep[fst[lx]] < deep[fst[rx]] ? lx : rx; } } } int query(int a, int b) { if (a == b) return a; a = fst[a], b = fst[b]; if (a > b) swap(a, b); int kk = lg2(b - a + 1); int lx = dp[a][kk], rx = dp[b - bit[kk] + 1][kk]; return deep[fst[lx]] < deep[fst[rx]] ? lx : rx; } int getDis(int a, int b) { int p = query(a, b); return dist[a] + dist[b] - 2 * dist[p]; }