From 07d9190a95ad4d2f03041417d8e73255b889424c Mon Sep 17 00:00:00 2001 From: Sagar Pandya Date: Wed, 28 Oct 2020 17:53:51 +0530 Subject: [PATCH 1/3] Documentation improved --- graph/connected_components_with_dsu.cpp | 86 ++++++++++++++++++------- 1 file changed, 62 insertions(+), 24 deletions(-) diff --git a/graph/connected_components_with_dsu.cpp b/graph/connected_components_with_dsu.cpp index 50d0c4242..191c2bc88 100644 --- a/graph/connected_components_with_dsu.cpp +++ b/graph/connected_components_with_dsu.cpp @@ -1,45 +1,79 @@ -#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. Use 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 +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 (int 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 + */ +int find_set(int val) { + if (val == parent[val]) { + return val; } - return parent[v] = find_set(parent[v]); + return parent[val] = find_set(parent[val]); } +/** + * @brief To join 2 components to belong to one + * @param a 1st component + * @param b 2nd component + * @returns void + */ +void union_sets(int a, int b) { + a = find_set(a); // find the parent of a + b = find_set(b); // find the parent of b -void union_sets(int a, int b) { // To join 2 components to belong to one - a = find_set(a); - b = find_set(b); + // If parents of both nodes are not same, combine them if (a != b) { if (connected_set_size[a] < connected_set_size[b]) { - std::swap(a, b); + std::swap(a, b); // swap both components } - parent[b] = a; - connected_set_size[a] += connected_set_size[b]; + parent[b] = a; // make a node as parent of b node. + connected_set_size[a] += connected_set_size[b]; // sum the size of both as they combined } } - -int no_of_connected_components() { // To find total no of connected components +/** + * @brief To find total no of connected components + * @return Number of connected components + */ +int 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(); + for (int 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); @@ -52,5 +86,9 @@ int main() { union_sets(node_a, node_b); } std::cout << no_of_connected_components() << std::endl; +} + +int main() { + test(); // Execute the tests return 0; } From f3e58c0f05cc7107e0a888d5c24617083ffc7671 Mon Sep 17 00:00:00 2001 From: Sagar Pandya Date: Wed, 28 Oct 2020 18:07:01 +0530 Subject: [PATCH 2/3] made find_set method efficient --- graph/connected_components_with_dsu.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/graph/connected_components_with_dsu.cpp b/graph/connected_components_with_dsu.cpp index 191c2bc88..c582d6f58 100644 --- a/graph/connected_components_with_dsu.cpp +++ b/graph/connected_components_with_dsu.cpp @@ -7,7 +7,7 @@ * * ### Algorithm * In Graph, if you have to find out the number of connected components, there are 2 options - * 1. Use Depth first search + * 1. Depth first search * 2. Disjoint union * 1st option is inefficient, Disjoint union is the most optimal way to find this. */ @@ -34,10 +34,11 @@ void make_set() { * @return parent of val */ int find_set(int val) { - if (val == parent[val]) { - return val; + while (parent[val] != val) { + parent[val] = parent[parent[val]]; + val = parent[val]; } - return parent[val] = find_set(parent[val]); + return val; } /** * @brief To join 2 components to belong to one From 5f873a7b111555fb803da81816526ac4e7fc7c93 Mon Sep 17 00:00:00 2001 From: Sagar Pandya Date: Wed, 28 Oct 2020 21:17:16 +0530 Subject: [PATCH 3/3] readability improved --- graph/connected_components_with_dsu.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/graph/connected_components_with_dsu.cpp b/graph/connected_components_with_dsu.cpp index c582d6f58..cd64a1bb2 100644 --- a/graph/connected_components_with_dsu.cpp +++ b/graph/connected_components_with_dsu.cpp @@ -42,21 +42,21 @@ int find_set(int val) { } /** * @brief To join 2 components to belong to one - * @param a 1st component - * @param b 2nd component + * @param node1 1st component + * @param node2 2nd component * @returns void */ -void union_sets(int a, int b) { - a = find_set(a); // find the parent of a - b = find_set(b); // find the parent of b +void union_sets(int node1, int node2) { + node1 = find_set(node1); // find the parent of node1 + node2 = find_set(node2); // find the parent of node2 // If parents of both nodes are not same, combine them - if (a != b) { - if (connected_set_size[a] < connected_set_size[b]) { - std::swap(a, b); // swap both components + if (node1 != node2) { + if (connected_set_size[node1] < connected_set_size[node2]) { + std::swap(node1, node2); // swap both components } - parent[b] = a; // make a node as parent of b node. - connected_set_size[a] += connected_set_size[b]; // sum the size of both as they combined + 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 } } /**