From a69051ac53b24635086a9ad792e2e132d53d887c Mon Sep 17 00:00:00 2001 From: Sagar Pandya Date: Fri, 8 Jan 2021 15:11:34 +0530 Subject: [PATCH] namespaces added datatype changed for big number documentation improved --- graph/connected_components_with_dsu.cpp | 122 +++++++++++++++++------- 1 file changed, 89 insertions(+), 33 deletions(-) diff --git a/graph/connected_components_with_dsu.cpp b/graph/connected_components_with_dsu.cpp index 50d0c4242..5317361b2 100644 --- a/graph/connected_components_with_dsu.cpp +++ b/graph/connected_components_with_dsu.cpp @@ -1,56 +1,112 @@ -#include -#include -#include +/** + * @file + * @brief [Disjoint union](https://en.wikipedia.org/wiki/Disjoint_union) + * + * @details + * The Disjoint union is the technique to find connected component in graph efficiently. + * + * ### Algorithm + * In Graph, if you have to find out the number of connected components, there are 2 options + * 1. Depth first search + * 2. Disjoint union + * 1st option is inefficient, Disjoint union is the most optimal way to find this. + */ +#include /// for io operations +#include /// for std::set +#include /// for std::vector -int number_of_nodes; // denotes number of nodes; -std::vector parent; -std::vector connected_set_size; -void make_set() { // function the initialize every node as it's own parent - for (int i = 1; i <= number_of_nodes; i++) { +/** + * @namespace graph + * @brief Graph Algorithms + */ +namespace graph { + +/** + * @namespace disjoint_union + * @brief Function for [Disjoint union] (https://en.wikipedia.org/wiki/Disjoint_union) implementation + */ +namespace disjoint_union { + +int64_t number_of_nodes; // denotes number of nodes +std::vector parent; // parent of each node +std::vector connected_set_size; // size of each set +/** + * @brief function the initialize every node as it's own parent + * @returns void + */ +void make_set() { + for (int64_t i = 1; i <= number_of_nodes; i++) { parent[i] = i; connected_set_size[i] = 1; } } -// To find the component where following node belongs to -int find_set(int v) { - if (v == parent[v]) { - return v; +/** + * @brief To find the component where following node belongs to + * @param val parent of val should be found + * @return parent of val + */ +int64_t find_set(int64_t val) { + while (parent[val] != val) { + parent[val] = parent[parent[val]]; + val = parent[val]; } - return parent[v] = find_set(parent[v]); + return val; } +/** + * @brief To join 2 components to belong to one + * @param node1 1st component + * @param node2 2nd component + * @returns void + */ +void union_sets(int64_t node1, int64_t node2) { + node1 = find_set(node1); // find the parent of node1 + node2 = find_set(node2); // find the parent of node2 -void union_sets(int a, int b) { // To join 2 components to belong to one - a = find_set(a); - b = find_set(b); - if (a != b) { - if (connected_set_size[a] < connected_set_size[b]) { - std::swap(a, b); + // If parents of both nodes are not same, combine them + if (node1 != node2) { + if (connected_set_size[node1] < connected_set_size[node2]) { + std::swap(node1, node2); // swap both components } - parent[b] = a; - connected_set_size[a] += connected_set_size[b]; + parent[node2] = node1; // make node1 as parent of node2. + connected_set_size[node1] += + connected_set_size[node2]; // sum the size of both as they combined } } - -int no_of_connected_components() { // To find total no of connected components - std::set temp; // temp set to count number of connected components - for (int i = 1; i <= number_of_nodes; i++) temp.insert(find_set(i)); - return temp.size(); +/** + * @brief To find total no of connected components + * @return Number of connected components + */ +int64_t no_of_connected_components() { + std::set temp; // temp set to count number of connected components + for (int64_t i = 1; i <= number_of_nodes; i++) temp.insert(find_set(i)); + return temp.size(); // return the size of temp set } - -// All critical/corner cases have been taken care of. -// Input your required values: (not hardcoded) -int main() { +/** + * @brief Test Implementations + * @returns void + */ +static void test() { std::cin >> number_of_nodes; parent.resize(number_of_nodes + 1); connected_set_size.resize(number_of_nodes + 1); make_set(); - int edges = 0; + int64_t edges = 0; std::cin >> edges; // no of edges in the graph while (edges--) { - int node_a = 0, node_b = 0; + int64_t node_a = 0, node_b = 0; std::cin >> node_a >> node_b; union_sets(node_a, node_b); } std::cout << no_of_connected_components() << std::endl; - return 0; } +} // namespace disjoint_union +} // namespace graph + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + graph::disjoint_union::test(); // Execute the tests + return 0; +} \ No newline at end of file