From ffa3fde34b667dff3ffe011e1f80f43ee02d2f82 Mon Sep 17 00:00:00 2001 From: Gloria Mundi Date: Tue, 27 Feb 2024 23:14:30 +0100 Subject: add LCA test and remove unused parent in DFS --- graph/test/LCA_sparse.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 graph/test/LCA_sparse.cpp (limited to 'graph/test') diff --git a/graph/test/LCA_sparse.cpp b/graph/test/LCA_sparse.cpp new file mode 100644 index 0000000..53af57b --- /dev/null +++ b/graph/test/LCA_sparse.cpp @@ -0,0 +1,90 @@ +#include +using namespace std; +using ll = long long; + +#define sz(x) ((int)(x).size()) +#define all(x) (x).begin(), (x).end() +#include "../../datastructures/sparseTable.cpp" +#include "../LCA_sparse.cpp" + +mt19937 rd(0); + +void test(const vector> &old_adj, int root) { + int n = old_adj.size(); + vector perm(n); + iota(perm.begin(), perm.end(), 0); + ranges::shuffle(perm, rd); + vector> adj(n); + for (int i = 0; i < n; i++) { + auto &a = adj[perm[i]] = old_adj[i]; + for (int &v: a) v = perm[v]; + ranges::shuffle(a, rd); + } + root = perm[root]; + + vector parent(n); + function dfs = [&](int u, int p) { + parent[u] = p; + for (int v: adj[u]) if (v != p) dfs(v, u); + }; + dfs(root, -1); + + function is_ancestor = [&](int u, int v) { + while (v != -1 && u != v) v = parent[v]; + return u == v; + }; + function depth = [&](int v) { + int r = 0; + while ((v = parent[v]) != -1) r++; + return r; + }; + + LCA lca; + lca.init(adj, root); + for (int i = 0; i < n; i++) assert(lca.getDepth(i) == depth(i)); + uniform_int_distribution distrib(0, n-1); + for (int i = 0; i < 1000; i++) { + int u = distrib(rd); + int v = distrib(rd); + int l = lca.getLCA(u, v); + assert(is_ancestor(l, u)); + assert(is_ancestor(l, v)); + for (int p = parent[l]; int c: adj[l]) { + if (c == p) continue; + assert(!is_ancestor(c, u) || !is_ancestor(c, v)); + } + } +} + +int main() { + { + // Single vertex + vector> adj(1); + test(adj, 0); + } + { + // Path + vector> adj(100); + for (int i = 1; i < 100; i++) { + adj[i-1].push_back(i); + adj[i].push_back(i-1); + } + test(adj, 0); + test(adj, 99); + test(adj, 40); + } + { + // Random + vector> adj(1000); + for (int i = 1; i < 1000; i++) { + uniform_int_distribution distrib(0, i-1); + int p = distrib(rd); + adj[p].push_back(i); + adj[i].push_back(p); + } + test(adj, 0); + test(adj, 300); + test(adj, 600); + test(adj, 900); + } +} -- cgit v1.2.3