Метод двоичного подъёма: различия между версиями
Перейти к навигации
Перейти к поиску
Ctrlalt (обсуждение | вклад) Нет описания правки |
Ctrlalt (обсуждение | вклад) Нет описания правки |
||
Строка 1: | Строка 1: | ||
struct Graph { | |||
vector<vector<int>> graph, ancestor; | |||
vector<int> l, r, depth; | |||
int timer = 0; | |||
Graph(int vertexCount) : | |||
graph(vertexCount), | |||
ancestor(vertexCount, vector<int>(20)), | |||
l(vertexCount), | |||
r(vertexCount), | |||
depth(vertexCount) {} | |||
void addEdge(int a, int b) { | |||
graph[a].push_back(b); | |||
graph[b].push_back(a); | |||
} | } | ||
void dfs(int v, int parent) { | |||
depth[v] = (v == parent ? 0 : depth[parent] + 1); | |||
== | l[v] = ++timer; | ||
ancestor[v][0] = parent; | |||
for (int i = 1; i < ancestor[v].size(); i++) | |||
ancestor[v][i] = ancestor[ancestor[v][i - 1]][i - 1]; | |||
[[ | for (int to : graph[v]) | ||
if (!l[to]) | |||
dfs(to, v); | |||
r[v] = ++timer; | |||
} | |||
void prepare(int root) { | |||
dfs(root, root); | |||
} | |||
bool isAncestor(int a, int b) { | |||
return l[a] <= l[b] && r[b] <= r[a]; | |||
} | |||
int lca(int a, int b) { | |||
if (isAncestor(a, b)) | |||
return a; | |||
if (isAncestor(b, a)) | |||
return b; | |||
for (int i = ancestor[a].size() - 1; i >= 0; i--) | |||
if (!isAncestor(ancestor[a][i], b)) | |||
a = ancestor[a][i]; | |||
return ancestor[a][0]; | |||
} | |||
int distance(int a, int b) { | |||
int l = lca(a, b); | |||
int da = depth[a] - depth[l]; | |||
int db = depth[b] - depth[l]; | |||
return da + db; | |||
} | |||
}; |
Версия от 08:13, 31 июля 2021
struct Graph { vector<vector<int>> graph, ancestor; vector<int> l, r, depth; int timer = 0; Graph(int vertexCount) : graph(vertexCount), ancestor(vertexCount, vector<int>(20)), l(vertexCount), r(vertexCount), depth(vertexCount) {} void addEdge(int a, int b) { graph[a].push_back(b); graph[b].push_back(a); } void dfs(int v, int parent) { depth[v] = (v == parent ? 0 : depth[parent] + 1); l[v] = ++timer; ancestor[v][0] = parent; for (int i = 1; i < ancestor[v].size(); i++) ancestor[v][i] = ancestor[ancestor[v][i - 1]][i - 1]; for (int to : graph[v]) if (!l[to]) dfs(to, v); r[v] = ++timer; } void prepare(int root) { dfs(root, root); } bool isAncestor(int a, int b) { return l[a] <= l[b] && r[b] <= r[a]; } int lca(int a, int b) { if (isAncestor(a, b)) return a; if (isAncestor(b, a)) return b; for (int i = ancestor[a].size() - 1; i >= 0; i--) if (!isAncestor(ancestor[a][i], b)) a = ancestor[a][i]; return ancestor[a][0]; } int distance(int a, int b) { int l = lca(a, b); int da = depth[a] - depth[l]; int db = depth[b] - depth[l]; return da + db; } };