99 * Algorithm: https://cp-algorithms.com/graph/lca_binary_lifting.html
1010 *
1111 * Complexity:
12- * - Precomputation: \f$O(N \log N)\f$ where \f$N\f$ is the number of vertices in the tree
12+ * - Precomputation: \f$O(N \log N)\f$ where \f$N\f$ is the number of vertices
13+ * in the tree
1314 * - Query: \f$O(\log N)\f$
1415 * - Space: \f$O(N \log N)\f$
1516 *
3435 * lowest_common_ancestor(x, y) = lowest_common_ancestor(y, x)
3536 */
3637
38+ #include < cassert>
3739#include < iostream>
40+ #include < queue>
3841#include < utility>
3942#include < vector>
40- #include < queue>
41- #include < cassert>
4243
4344/* *
4445 * \namespace graph
@@ -50,15 +51,15 @@ namespace graph {
5051 * Its vertices are indexed 0, 1, ..., N - 1.
5152 */
5253class Graph {
53- public:
54+ public:
5455 /* *
5556 * \brief Populate the adjacency list for each vertex in the graph.
5657 * Assumes that evey edge is a pair of valid vertex indices.
5758 *
5859 * @param N number of vertices in the graph
5960 * @param undirected_edges list of graph's undirected edges
6061 */
61- Graph (size_t N, const std::vector< std::pair<int , int > > &undirected_edges) {
62+ Graph (size_t N, const std::vector<std::pair<int , int > > &undirected_edges) {
6263 neighbors.resize (N);
6364 for (auto &edge : undirected_edges) {
6465 neighbors[edge.first ].push_back (edge.second );
@@ -70,27 +71,27 @@ class Graph {
7071 * Function to get the number of vertices in the graph
7172 * @return the number of vertices in the graph.
7273 */
73- int number_of_vertices () const {
74- return neighbors.size ();
75- }
74+ int number_of_vertices () const { return neighbors.size (); }
7675
7776 /* * \brief for each vertex it stores a list indicies of its neighbors */
78- std::vector< std::vector<int > > neighbors;
77+ std::vector<std::vector<int > > neighbors;
7978};
8079
8180/* *
82- * Representation of a rooted tree. For every vertex its parent is precalculated.
81+ * Representation of a rooted tree. For every vertex its parent is
82+ * precalculated.
8383 */
8484class RootedTree : public Graph {
85- public:
85+ public:
8686 /* *
8787 * \brief Constructs the tree by calculating parent for every vertex.
8888 * Assumes a valid description of a tree is provided.
8989 *
9090 * @param undirected_edges list of graph's undirected edges
9191 * @param root_ index of the root vertex
9292 */
93- RootedTree (const std::vector< std::pair<int , int > > &undirected_edges, int root_)
93+ RootedTree (const std::vector<std::pair<int , int > > &undirected_edges,
94+ int root_)
9495 : Graph(undirected_edges.size() + 1 , undirected_edges), root(root_) {
9596 populate_parents ();
9697 }
@@ -106,7 +107,7 @@ class RootedTree : public Graph {
106107 /* * \brief Index of the root vertex. */
107108 int root;
108109
109- protected:
110+ protected:
110111 /* *
111112 * \brief Calculate the parents for all the vertices in the tree.
112113 * Implements the breadth first search algorithm starting from the root
@@ -135,21 +136,20 @@ class RootedTree : public Graph {
135136 }
136137 }
137138 }
138-
139139};
140140
141141/* *
142142 * A structure that holds a rooted tree and allow for effecient
143143 * queries of the lowest common ancestor of two given vertices in the tree.
144144 */
145145class LowestCommonAncestor {
146- public:
146+ public:
147147 /* *
148148 * \brief Stores the tree and precomputs "up lifts".
149149 * @param tree_ rooted tree.
150150 */
151- explicit LowestCommonAncestor (const RootedTree& tree_) : tree(tree_) {
152- populate_up ();
151+ explicit LowestCommonAncestor (const RootedTree & tree_) : tree(tree_) {
152+ populate_up ();
153153 }
154154
155155 /* *
@@ -196,16 +196,16 @@ class LowestCommonAncestor {
196196 }
197197
198198 /* \brief reference to the rooted tree this structure allows to query */
199- const RootedTree& tree;
199+ const RootedTree & tree;
200200 /* *
201201 * \brief for every vertex stores a list of its ancestors by powers of two
202202 * For each vertex, the first element of the corresponding list contains
203203 * the index of its parent. The i-th element of the list is an index of
204204 * the (2^i)-th ancestor of the vertex.
205205 */
206- std::vector< std::vector<int > > up;
206+ std::vector<std::vector<int > > up;
207207
208- protected:
208+ protected:
209209 /* *
210210 * Populate the "up" structure. See above.
211211 */
@@ -241,9 +241,8 @@ static void tests() {
241241 * |
242242 * 9
243243 */
244- std::vector< std::pair<int , int > > edges = {
245- {7 , 1 }, {1 , 5 }, {1 , 3 }, {3 , 6 }, {6 , 2 }, {2 , 9 }, {6 , 8 }, {4 , 3 }, {0 , 4 }
246- };
244+ std::vector<std::pair<int , int > > edges = {
245+ {7 , 1 }, {1 , 5 }, {1 , 3 }, {3 , 6 }, {6 , 2 }, {2 , 9 }, {6 , 8 }, {4 , 3 }, {0 , 4 }};
247246 graph::RootedTree t (edges, 3 );
248247 graph::LowestCommonAncestor lca (t);
249248 assert (lca.lowest_common_ancestor (7 , 4 ) == 3 );
0 commit comments