Метод двоичного подъёма
Перейти к навигации
Перейти к поиску
void dfs(int v, int parent) { //если v - корень, то parent == v tIn[v] = timer++; p[v][0] = parent; for (int i = 1; i < MAX_H; i++) p[v][i] = p[p[v][i - 1]][i - 1]; for (int i = 0; i < g[v].size(); i++) dfs(g[v][i], v); tOut[v] = timer++; } bool isAncestor(int a, int b) { return tIn[a] <= tIn[b] && tOut[b] <= tOut[a]; } int lca(int a, int b) { if (isAncestor(a, b)) return a; if (isAncestor(b, a)) return b; for (int i = MAX_H - 1; i >= 0; i--) { if (!isAncestor(p[a][i], b)) a = p[a][i]; } return p[a][0]; }
Ссылки
- e-maxx.ru — Наименьший общий предок. Нахождение за O(log N) (метод двоичного подъёма)
- neerc.ifmo.ru/wiki — Метод двоичного подъёма
- CodeLibrary — LCA: Sparse Table (несмотря на название, приведён код метода двоичного подъёма)
- Algos — Finding LCA (Least common ancestor) of two vertices in the tree