From b94c29ce016dedf785721cbac353c18fd1a486df Mon Sep 17 00:00:00 2001 From: AkVaya Date: Fri, 14 Aug 2020 00:23:51 +0530 Subject: [PATCH 01/11] Added is_graph_bipartite.cpp --- graph/is_graph_bipartite.cpp | 135 +++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 graph/is_graph_bipartite.cpp diff --git a/graph/is_graph_bipartite.cpp b/graph/is_graph_bipartite.cpp new file mode 100644 index 000000000..7d6df310d --- /dev/null +++ b/graph/is_graph_bipartite.cpp @@ -0,0 +1,135 @@ +/** + * @file is_graph_bipartite + * + * @brief Algorithm to check whether a graph is bipartite + * + * @details + * A graph is a collection of nodes also called vertices and these vertices + * are connected by edges.A bipartite graph is a graph whose vertices can be + * divided into two disjoint and independent sets U and V such that every edge + * connects a vertex in U to one in V. + * (https://en.wikipedia.org/wiki/Bipartite_graph) + * The given Algorithm will determine whether the given graph is bipartite or not + * + * + * Example - Here is a graph g1 with 5 vertices and is bipartite + * + * 1 4 + * / \ / \ + * 2 3 5 + * + * Example - Here is a graph G2 with 3 vertices and is not bipartite + * + * 1 --- 2 + * \ / + * 3 + * + * + * @author [Akshat Vaya](https://github.com/AkVaya) + * + */ +#include +#include +#include + +using std::vector; +using std::queue; + +const int nax = 5e5 + 1; +/** + * Class for representing graph as an adjacency list. + */ +class graph { + private: + int n; /// size of the graph + + vector > adj; /// adj stores the graph as an adjacency list + + vector side; ///stores the side of the vertex + + public: + /** + * @brief Constructor that initializes the graph on creation + */ + graph(int size = nax){ + n = size; + adj.resize(n); + side.resize(n,-1); + } + + void addEdge(int u, int v); /// function to add edges to our graph + + bool is_bipartite(); /// function to check whether the graph is bipartite or not + +}; +/** + * @brief Function that add an edge between two nodes or vertices of graph + * + * @param u is a node or vertex of graph + * @param v is a node or vertex of graph + */ +void graph::addEdge(int u, int v) { + adj[u-1].push_back(v-1); + adj[v-1].push_back(u-1); +} +/** + * @brief function that checks whether the graph is bipartite or not + */ +bool graph::is_bipartite(){ + n = adj.size(); + side.resize(n,-1); + bool check = true; + queue q; + for (int current_edge = 0; current_edge < n; ++current_edge) + { + if(side[current_edge] == -1){ + q.push(current_edge); + side[current_edge] = 0; + while(q.size()){ + int current = q.front(); + q.pop(); + for(auto neighbour : adj[current]){ + if(side[neighbour] == -1){ + side[neighbour] = (1 ^ side[current]); + q.push(neighbour); + } + else{ + check &= (side[neighbour] != side[current]); + } + } + } + } + } + return check; +} +/** + * main funtion + */ +int main(){ + graph G1(5); /// creating graph G1 with 5 vertices + /// adding edges to the graphs as per the illustrated example + G1.addEdge(1,2); + G1.addEdge(1,3); + G1.addEdge(3,4); + G1.addEdge(4,5); + + graph G2(3); /// creating graph G2 with 3 vertices + /// adding edges to the graphs as per the illustrated example + G2.addEdge(1,2); + G2.addEdge(1,3); + G2.addEdge(2,3); + /// checking whether the graphs are bipartite or not + if(G1.is_bipartite()){ + std::cout<<"The given graph G1 is a bipartite graph\n"; + } + else{ + std::cout<<"The given graph G1 is not a bipartite graph\n"; + } + if(G2.is_bipartite()){ + std::cout<<"The given graph G2 is a bipartite graph\n"; + } + else{ + std::cout<<"The given graph G2 is not a bipartite graph\n"; + } + return 0; +} \ No newline at end of file From 97f3e1a0769cf4796a2507bc93c66b6adb600757 Mon Sep 17 00:00:00 2001 From: AkVaya Date: Fri, 14 Aug 2020 01:06:24 +0530 Subject: [PATCH 02/11] Perfomed the requested changes --- graph/is_graph_bipartite.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/graph/is_graph_bipartite.cpp b/graph/is_graph_bipartite.cpp index 7d6df310d..f0d0ef098 100644 --- a/graph/is_graph_bipartite.cpp +++ b/graph/is_graph_bipartite.cpp @@ -103,7 +103,7 @@ bool graph::is_bipartite(){ return check; } /** - * main funtion + * Main funtion */ int main(){ graph G1(5); /// creating graph G1 with 5 vertices @@ -132,4 +132,4 @@ int main(){ std::cout<<"The given graph G2 is not a bipartite graph\n"; } return 0; -} \ No newline at end of file +} From d87a6685f623ddc7cba3f1cbd1287d6d69630885 Mon Sep 17 00:00:00 2001 From: AkVaya Date: Fri, 14 Aug 2020 01:43:57 +0530 Subject: [PATCH 03/11] Performed the requested changes --- graph/is_graph_bipartite.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/graph/is_graph_bipartite.cpp b/graph/is_graph_bipartite.cpp index f0d0ef098..718ea9853 100644 --- a/graph/is_graph_bipartite.cpp +++ b/graph/is_graph_bipartite.cpp @@ -2,13 +2,14 @@ * @file is_graph_bipartite * * @brief Algorithm to check whether a graph is bipartite + * (https://en.wikipedia.org/wiki/Bipartite_graph) * * @details * A graph is a collection of nodes also called vertices and these vertices * are connected by edges.A bipartite graph is a graph whose vertices can be * divided into two disjoint and independent sets U and V such that every edge * connects a vertex in U to one in V. - * (https://en.wikipedia.org/wiki/Bipartite_graph) + * * The given Algorithm will determine whether the given graph is bipartite or not * * @@ -32,9 +33,6 @@ #include #include -using std::vector; -using std::queue; - const int nax = 5e5 + 1; /** * Class for representing graph as an adjacency list. @@ -43,9 +41,9 @@ class graph { private: int n; /// size of the graph - vector > adj; /// adj stores the graph as an adjacency list + std::vector > adj; /// adj stores the graph as an adjacency list - vector side; ///stores the side of the vertex + std::vector side; ///stores the side of the vertex public: /** @@ -74,12 +72,14 @@ void graph::addEdge(int u, int v) { } /** * @brief function that checks whether the graph is bipartite or not + * the function returns true if the graph is a bipartite graph + * the function returns false if the graph is not a bipartite graph */ bool graph::is_bipartite(){ n = adj.size(); side.resize(n,-1); bool check = true; - queue q; + std::queue q; for (int current_edge = 0; current_edge < n; ++current_edge) { if(side[current_edge] == -1){ @@ -103,9 +103,9 @@ bool graph::is_bipartite(){ return check; } /** - * Main funtion + * Function to test the above algorithm */ -int main(){ +void test(){ graph G1(5); /// creating graph G1 with 5 vertices /// adding edges to the graphs as per the illustrated example G1.addEdge(1,2); @@ -118,6 +118,7 @@ int main(){ G2.addEdge(1,2); G2.addEdge(1,3); G2.addEdge(2,3); + /// checking whether the graphs are bipartite or not if(G1.is_bipartite()){ std::cout<<"The given graph G1 is a bipartite graph\n"; @@ -131,5 +132,11 @@ int main(){ else{ std::cout<<"The given graph G2 is not a bipartite graph\n"; } +} +/** + * Main function + */ +int main(){ + test(); ///Testing return 0; } From ab26183183585147498b1a6b077c7aa34f69bb0d Mon Sep 17 00:00:00 2001 From: AkVaya Date: Fri, 14 Aug 2020 10:04:21 +0530 Subject: [PATCH 04/11] Performed the requested changes --- graph/is_graph_bipartite.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/graph/is_graph_bipartite.cpp b/graph/is_graph_bipartite.cpp index 718ea9853..86b82b781 100644 --- a/graph/is_graph_bipartite.cpp +++ b/graph/is_graph_bipartite.cpp @@ -1,9 +1,8 @@ /** * @file is_graph_bipartite * - * @brief Algorithm to check whether a graph is bipartite - * (https://en.wikipedia.org/wiki/Bipartite_graph) - * + * @brief Algorithm to check whether a graph is [bipartite](https://en.wikipedia.org/wiki/Bipartite_graph) + * * @details * A graph is a collection of nodes also called vertices and these vertices * are connected by edges.A bipartite graph is a graph whose vertices can be @@ -11,20 +10,19 @@ * connects a vertex in U to one in V. * * The given Algorithm will determine whether the given graph is bipartite or not - * - * + * + * * Example - Here is a graph g1 with 5 vertices and is bipartite - * + * * 1 4 * / \ / \ * 2 3 5 * * Example - Here is a graph G2 with 3 vertices and is not bipartite - * + * * 1 --- 2 * \ / * 3 - * * * @author [Akshat Vaya](https://github.com/AkVaya) * @@ -74,10 +72,16 @@ void graph::addEdge(int u, int v) { * @brief function that checks whether the graph is bipartite or not * the function returns true if the graph is a bipartite graph * the function returns false if the graph is not a bipartite graph + * + * @details + * Here, side refers to the two disjoint subsets of the bipartite graph. + * Initially, the values of side are set to -1 which is an unassigned state. A for loop is run for every vertex of the graph. + * If the current edge has no side assigned to it, then a Breadth First Search operation is performed. + * If two neighbours have the same side then the graph will not be bipartite and the value of check becomes false. + * If and only if each pair of neighbours have different sides, the value of check will be true and hence the graph bipartite. + * */ bool graph::is_bipartite(){ - n = adj.size(); - side.resize(n,-1); bool check = true; std::queue q; for (int current_edge = 0; current_edge < n; ++current_edge) From 4c0b1a76b5cfbffc7181f13bb8b15d03455d4127 Mon Sep 17 00:00:00 2001 From: fzxutar <68406506+fzxutar@users.noreply.github.com> Date: Fri, 14 Aug 2020 19:58:40 +0800 Subject: [PATCH 05/11] test: add test for fibonacci() function --- math/fibonacci.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/math/fibonacci.cpp b/math/fibonacci.cpp index e15cfc0cc..2a79a8186 100644 --- a/math/fibonacci.cpp +++ b/math/fibonacci.cpp @@ -24,8 +24,39 @@ int fibonacci(unsigned int n) { return fibonacci(n - 1) + fibonacci(n - 2); } +/** + * Function for testing the fibonacci() function with a few + * test cases and assert statement. + */ +void test() { + int test_case_1 = fibonacci(0); + assert(test_case_1 == 0); + std::cout << "Passed Test 1!" << std::endl; + + int test_case_2 = fibonacci(1); + assert(test_case_2 == 1); + std::cout << "Passed Test 2!" << std::endl; + + int test_case_3 = fibonacci(2); + assert(test_case_3 == 1); + std::cout << "Passed Test 3!" << std::endl; + + int test_case_4 = fibonacci(3); + assert(test_case_4 == 2); + std::cout << "Passed Test 4!" << std::endl; + + int test_case_5 = fibonacci(4); + assert(test_case_5 == 3); + std::cout << "Passed Test 5!" << std::endl; + + int test_case_6 = fibonacci(15); + assert(test_case_6 == 610); + std::cout << "Passed Test 6!" << std::endl << std::endl; +} + /// Main function int main() { + test(); int n; std::cin >> n; assert(n >= 0); From 3e355d0f7ad5bc8afdcfa1f8c53afc967ac16fd5 Mon Sep 17 00:00:00 2001 From: AkVaya Date: Sat, 15 Aug 2020 00:53:31 +0530 Subject: [PATCH 06/11] Performed the requested changes --- graph/is_graph_bipartite.cpp | 156 +++++++++++++++++++---------------- 1 file changed, 86 insertions(+), 70 deletions(-) diff --git a/graph/is_graph_bipartite.cpp b/graph/is_graph_bipartite.cpp index 86b82b781..426d25560 100644 --- a/graph/is_graph_bipartite.cpp +++ b/graph/is_graph_bipartite.cpp @@ -31,93 +31,109 @@ #include #include -const int nax = 5e5 + 1; /** * Class for representing graph as an adjacency list. */ -class graph { - private: - int n; /// size of the graph - - std::vector > adj; /// adj stores the graph as an adjacency list - - std::vector side; ///stores the side of the vertex - - public: - /** - * @brief Constructor that initializes the graph on creation - */ - graph(int size = nax){ - n = size; - adj.resize(n); - side.resize(n,-1); - } - - void addEdge(int u, int v); /// function to add edges to our graph - - bool is_bipartite(); /// function to check whether the graph is bipartite or not - -}; /** - * @brief Function that add an edge between two nodes or vertices of graph - * - * @param u is a node or vertex of graph - * @param v is a node or vertex of graph + * @namespace graph + * @brief Graph algorithms */ -void graph::addEdge(int u, int v) { - adj[u-1].push_back(v-1); - adj[v-1].push_back(u-1); -} -/** - * @brief function that checks whether the graph is bipartite or not - * the function returns true if the graph is a bipartite graph - * the function returns false if the graph is not a bipartite graph - * - * @details - * Here, side refers to the two disjoint subsets of the bipartite graph. - * Initially, the values of side are set to -1 which is an unassigned state. A for loop is run for every vertex of the graph. - * If the current edge has no side assigned to it, then a Breadth First Search operation is performed. - * If two neighbours have the same side then the graph will not be bipartite and the value of check becomes false. - * If and only if each pair of neighbours have different sides, the value of check will be true and hence the graph bipartite. - * - */ -bool graph::is_bipartite(){ - bool check = true; - std::queue q; - for (int current_edge = 0; current_edge < n; ++current_edge) - { - if(side[current_edge] == -1){ - q.push(current_edge); - side[current_edge] = 0; - while(q.size()){ - int current = q.front(); - q.pop(); - for(auto neighbour : adj[current]){ - if(side[neighbour] == -1){ - side[neighbour] = (1 ^ side[current]); - q.push(neighbour); - } - else{ - check &= (side[neighbour] != side[current]); +namespace graph{ + /** + * @namespace is_graph_bipartite + * @brief Functions for checking whether a graph is bipartite or not + */ + namespace is_graph_bipartite{ + + class Graph { + private: + int n; /// size of the graph + + std::vector > adj; /// adj stores the graph as an adjacency list + + std::vector side; ///stores the side of the vertex + + static const int nax = 5e5 + 1; + + + public: + /** + * @brief Constructor that initializes the graph on creation + */ + explicit Graph(int size = nax){ + n = size; + adj.resize(n); + side.resize(n,-1); + } + + void addEdge(int u, int v); /// function to add edges to our graph + + bool is_bipartite(); /// function to check whether the graph is bipartite or not + + }; + /** + * @brief Function that add an edge between two nodes or vertices of graph + * + * @param u is a node or vertex of graph + * @param v is a node or vertex of graph + */ + void Graph::addEdge(int u, int v) { + adj[u-1].push_back(v-1); + adj[v-1].push_back(u-1); + } + /** + * @brief function that checks whether the graph is bipartite or not + * the function returns true if the graph is a bipartite graph + * the function returns false if the graph is not a bipartite graph + * + * @details + * Here, side refers to the two disjoint subsets of the bipartite graph. + * Initially, the values of side are set to -1 which is an unassigned state. A for loop is run for every vertex of the graph. + * If the current edge has no side assigned to it, then a Breadth First Search operation is performed. + * If two neighbours have the same side then the graph will not be bipartite and the value of check becomes false. + * If and only if each pair of neighbours have different sides, the value of check will be true and hence the graph bipartite. + * + */ + bool Graph::is_bipartite(){ + bool check = true; + std::queue q; + for (int current_edge = 0; current_edge < n; ++current_edge) + { + if(side[current_edge] == -1){ + q.push(current_edge); + side[current_edge] = 0; + while(q.size()){ + int current = q.front(); + q.pop(); + for(auto neighbour : adj[current]){ + if(side[neighbour] == -1){ + side[neighbour] = (1 ^ side[current]); + q.push(neighbour); + } + else{ + check &= (side[neighbour] != side[current]); + } + } } } } + return check; } - } - return check; -} + } /// namespace is_graph_bipartite +} /// namespace graph /** - * Function to test the above algorithm + * Function to test the above algorithm + * @returns none */ -void test(){ - graph G1(5); /// creating graph G1 with 5 vertices +static void test(){ + graph::is_graph_bipartite::Graph G1(5); /// creating graph G1 with 5 vertices /// adding edges to the graphs as per the illustrated example G1.addEdge(1,2); G1.addEdge(1,3); G1.addEdge(3,4); G1.addEdge(4,5); - graph G2(3); /// creating graph G2 with 3 vertices + graph::is_graph_bipartite::Graph G2(3); /// creating graph G2 with 3 vertices /// adding edges to the graphs as per the illustrated example G2.addEdge(1,2); G2.addEdge(1,3); From e248a614e58cd377f8960db117df174ba13172ed Mon Sep 17 00:00:00 2001 From: AkVaya Date: Sat, 15 Aug 2020 01:58:23 +0530 Subject: [PATCH 07/11] Performed requested changes --- graph/is_graph_bipartite.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/graph/is_graph_bipartite.cpp b/graph/is_graph_bipartite.cpp index 426d25560..db73a72af 100644 --- a/graph/is_graph_bipartite.cpp +++ b/graph/is_graph_bipartite.cpp @@ -32,11 +32,8 @@ #include /** - * Class for representing graph as an adjacency list. - */ -/** - * @namespace graph - * @brief Graph algorithms + * @namespace graph + * @brief Graph algorithms */ namespace graph{ /** @@ -44,7 +41,9 @@ namespace graph{ * @brief Functions for checking whether a graph is bipartite or not */ namespace is_graph_bipartite{ - + /** + * @brief Class for representing graph as an adjacency list. + */ class Graph { private: int n; /// size of the graph @@ -57,9 +56,9 @@ namespace graph{ public: - /** - * @brief Constructor that initializes the graph on creation - */ + /** + * @brief Constructor that initializes the graph on creation + */ explicit Graph(int size = nax){ n = size; adj.resize(n); From cc64ca66b0cb6a25f7a820c5747b12669a538263 Mon Sep 17 00:00:00 2001 From: fzxutar <68406506+fzxutar@users.noreply.github.com> Date: Sat, 15 Aug 2020 12:51:06 +0800 Subject: [PATCH 08/11] [Updated] test: add test for fibonacci() function Fixed the errors as suggested by the author. --- math/fibonacci.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/math/fibonacci.cpp b/math/fibonacci.cpp index 2a79a8186..493523b61 100644 --- a/math/fibonacci.cpp +++ b/math/fibonacci.cpp @@ -14,7 +14,7 @@ /** * Recursively compute sequences */ -int fibonacci(unsigned int n) { +unsigned int fibonacci(unsigned int n) { /* If the input is 0 or 1 just return the same This will set the first 2 values of the sequence */ if (n <= 1) @@ -27,29 +27,30 @@ int fibonacci(unsigned int n) { /** * Function for testing the fibonacci() function with a few * test cases and assert statement. - */ -void test() { - int test_case_1 = fibonacci(0); + * @returns `void` +*/ +static void test() { + unsigned int test_case_1 = fibonacci(0); assert(test_case_1 == 0); std::cout << "Passed Test 1!" << std::endl; - int test_case_2 = fibonacci(1); + unsigned int test_case_2 = fibonacci(1); assert(test_case_2 == 1); std::cout << "Passed Test 2!" << std::endl; - int test_case_3 = fibonacci(2); + unsigned int test_case_3 = fibonacci(2); assert(test_case_3 == 1); std::cout << "Passed Test 3!" << std::endl; - int test_case_4 = fibonacci(3); + unsigned int test_case_4 = fibonacci(3); assert(test_case_4 == 2); std::cout << "Passed Test 4!" << std::endl; - int test_case_5 = fibonacci(4); + unsigned int test_case_5 = fibonacci(4); assert(test_case_5 == 3); std::cout << "Passed Test 5!" << std::endl; - int test_case_6 = fibonacci(15); + unsigned int test_case_6 = fibonacci(15); assert(test_case_6 == 610); std::cout << "Passed Test 6!" << std::endl << std::endl; } From fd6b8100614e97b30056eb48744cb4fc8cbd32b9 Mon Sep 17 00:00:00 2001 From: AkVaya Date: Sat, 15 Aug 2020 10:58:51 +0530 Subject: [PATCH 09/11] Performed the requested changes --- graph/is_graph_bipartite.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/graph/is_graph_bipartite.cpp b/graph/is_graph_bipartite.cpp index db73a72af..baadf71fa 100644 --- a/graph/is_graph_bipartite.cpp +++ b/graph/is_graph_bipartite.cpp @@ -1,5 +1,5 @@ /** - * @file is_graph_bipartite + * @file * * @brief Algorithm to check whether a graph is [bipartite](https://en.wikipedia.org/wiki/Bipartite_graph) * @@ -11,7 +11,7 @@ * * The given Algorithm will determine whether the given graph is bipartite or not * - * + *
  * 	Example - Here is a graph g1 with 5 vertices and is bipartite
  *	
  *		1   4
@@ -24,6 +24,8 @@
  *		 \   /
  *		   3
  *	
+ *	
+ * * @author [Akshat Vaya](https://github.com/AkVaya) * */ From c1961d7c2ba7ddc82c55f40ad40e1317dc2f1bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Hl=C3=A1sek?= Date: Sat, 15 Aug 2020 15:54:16 -0700 Subject: [PATCH 10/11] fix: linter for dijkstra --- graph/dijkstra.cpp | 222 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 175 insertions(+), 47 deletions(-) diff --git a/graph/dijkstra.cpp b/graph/dijkstra.cpp index 650f0cd51..ac269de18 100644 --- a/graph/dijkstra.cpp +++ b/graph/dijkstra.cpp @@ -1,52 +1,180 @@ -#include +/** + * @file + * @brief [Graph Dijkstras Shortest Path Algorithm + * (Dijkstra's Shortest Path)] + * (https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) + * + * @author [Ayaan Khan](http://github.com/ayaankhan98) + * + * @details + * Dijkstra's Algorithm is used to find the shortest path from a source + * vertex to all other reachable vertex in the graph. + * The algorithm initially assumes all the nodes are unreachable from the + * given source vertex so we mark the distances of all vertices as INF + * (infinity) from source vertex (INF / infinity denotes unable to reach). + * + * in similar fashion with BFS we assume the distance of source vertex as 0 + * and pushes the vertex in a priority queue with it's distance. + * we maintain the priority queue as a min heap so that we can get the + * minimum element at the top of heap + * + * Basically what we do in this algorithm is that we try to minimize the + * distances of all the reachable vertices from the current vertex, look + * at the code below to understand in better way. + * + */ +#include #include +#include #include +#include #include -using namespace std; -#define INF 10000010 -vector> graph[5 * 100001]; -int dis[5 * 100001]; -int dij(vector> *v, int s, int *dis) { - priority_queue, vector>, - greater>> - pq; - // source distance to zero. - pq.push(make_pair(0, s)); - dis[s] = 0; - int u; - while (!pq.empty()) { - u = (pq.top()).second; - pq.pop(); - for (vector>::iterator it = v[u].begin(); - it != v[u].end(); it++) { - if (dis[u] + it->first < dis[it->second]) { - dis[it->second] = dis[u] + it->first; - pq.push(make_pair(dis[it->second], it->second)); - } - } - } -} -int main() { - int m, n, l, x, y, s; - // n--> number of nodes , m --> number of edges - cin >> n >> m; - for (int i = 0; i < m; i++) { - // input edges. - scanf("%d%d%d", &x, &y, &l); - graph[x].push_back(make_pair(l, y)); - graph[y].push_back( - make_pair(l, x)); // comment this line for directed graph - } - // start node. - scanf("%d", &s); - // intialise all distances to infinity. - for (int i = 1; i <= n; i++) dis[i] = INF; - dij(graph, s, dis); +#include - for (int i = 1; i <= n; i++) - if (dis[i] == INF) - cout << "-1 "; - else - cout << dis[i] << " "; - return 0; +constexpr int64_t INF = std::numeric_limits::max(); + +/** + * @namespace graph + * @brief Graph Algorithms + */ + +namespace graph { + /** + * @brief Function that add edge between two nodes or vertices of graph + * + * @param u any node or vertex of graph + * @param v any node or vertex of graph + */ + void addEdge(std::vector>> *adj, int u, int v, + int w) { + (*adj)[u - 1].push_back(std::make_pair(v - 1, w)); + // (*adj)[v - 1].push_back(std::make_pair(u - 1, w)); + } + + /** + * @brief Function runs the dijkstra algorithm for some source vertex and + * target vertex in the graph and returns the shortest distance of target + * from the source. + * + * @param adj input graph + * @param s source vertex + * @param t target vertex + * + * @return shortest distance if target is reachable from source else -1 in + * case if target is not reachable from source. + */ + int dijkstra(std::vector>> *adj, int s, int t) { + /// n denotes the number of vertices in graph + int n = adj->size(); + + /// setting all the distances initially to INF + std::vector dist(n, INF); + + /// creating a min heap using priority queue + /// first element of pair contains the distance + /// second element of pair contains the vertex + std::priority_queue, std::vector>, + std::greater>> + pq; + + /// pushing the source vertex 's' with 0 distance in min heap + pq.push(std::make_pair(0, s)); + + /// marking the distance of source as 0 + dist[s] = 0; + + while (!pq.empty()) { + /// second element of pair denotes the node / vertex + int currentNode = pq.top().second; + + /// first element of pair denotes the distance + int currentDist = pq.top().first; + + pq.pop(); + + /// for all the reachable vertex from the currently exploring vertex + /// we will try to minimize the distance + for (std::pair edge : (*adj)[currentNode]) { + /// minimizing distances + if (currentDist + edge.second < dist[edge.first]) { + dist[edge.first] = currentDist + edge.second; + pq.push(std::make_pair(dist[edge.first], edge.first)); + } + } + } + if (dist[t] != INF) { + return dist[t]; + } + return -1; + } +} // namespace graph + +/** Function to test the Algorithm */ +void tests() { + std::cout << "Initiatinig Predefined Tests..." << std::endl; + std::cout << "Initiating Test 1..." << std::endl; + std::vector>> adj1( + 4, std::vector>()); + graph::addEdge(&adj1, 1, 2, 1); + graph::addEdge(&adj1, 4, 1, 2); + graph::addEdge(&adj1, 2, 3, 2); + graph::addEdge(&adj1, 1, 3, 5); + + int s = 1, t = 3; + assert(graph::dijkstra(&adj1, s - 1, t - 1) == 3); + std::cout << "Test 1 Passed..." << std::endl; + + s = 4, t = 3; + std::cout << "Initiating Test 2..." << std::endl; + assert(graph::dijkstra(&adj1, s - 1, t - 1) == 5); + std::cout << "Test 2 Passed..." << std::endl; + + std::vector>> adj2( + 5, std::vector>()); + graph::addEdge(&adj2, 1, 2, 4); + graph::addEdge(&adj2, 1, 3, 2); + graph::addEdge(&adj2, 2, 3, 2); + graph::addEdge(&adj2, 3, 2, 1); + graph::addEdge(&adj2, 2, 4, 2); + graph::addEdge(&adj2, 3, 5, 4); + graph::addEdge(&adj2, 5, 4, 1); + graph::addEdge(&adj2, 2, 5, 3); + graph::addEdge(&adj2, 3, 4, 4); + + s = 1, t = 5; + std::cout << "Initiating Test 3..." << std::endl; + assert(graph::dijkstra(&adj2, s - 1, t - 1) == 6); + std::cout << "Test 3 Passed..." << std::endl; + std::cout << "All Test Passed..." << std::endl << std::endl; +} + +/** Main function */ +int main() { + // running predefined tests + tests(); + + int vertices = int(), edges = int(); + std::cout << "Enter the number of vertices : "; + std::cin >> vertices; + std::cout << "Enter the number of edges : "; + std::cin >> edges; + + std::vector>> adj( + vertices, std::vector>()); + + int u = int(), v = int(), w = int(); + while (edges--) { + std::cin >> u >> v >> w; + graph::addEdge(&adj, u, v, w); + } + + int s = int(), t = int(); + std::cin >> s >> t; + int dist = graph::dijkstra(&adj, s - 1, t - 1); + if (dist == -1) { + std::cout << "Target not reachable from source" << std::endl; + } else { + std::cout << "Shortest Path Distance : " << dist << std::endl; + } + return 0; } From 2c41598e379f746dc91bd28d8a64c8c3e7bcf839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Hl=C3=A1sek?= Date: Sat, 15 Aug 2020 15:57:45 -0700 Subject: [PATCH 11/11] fix: linter for connected_components. --- graph/connected_components.cpp | 162 +++++++++++++++++++-------------- 1 file changed, 94 insertions(+), 68 deletions(-) diff --git a/graph/connected_components.cpp b/graph/connected_components.cpp index e53dbf424..06bb1ee50 100644 --- a/graph/connected_components.cpp +++ b/graph/connected_components.cpp @@ -15,9 +15,9 @@ *
  * Example - Here is graph with 3 connected components
  *
- *      3   9           6               8
+ *      1   4           5               8
  *     / \ /           / \             / \
- *    2---4           2   7           3   7
+ *    2---3           6   7           9   10
  *
  *    first          second           third
  *    component      component        component
@@ -26,97 +26,123 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 
-using std::vector;
-
 /**
- * Class for representing graph as a adjacency list.
+ * @namespace graph
+ * @brief Graph Algorithms
  */
-class graph {
- private:
-    /** \brief adj stores adjacency list representation of graph */
-    vector> adj;
-
-    /** \brief keep track of connected components */
-    int connected_components;
-
-    void depth_first_search();
-    void explore(int, vector &);
-
- public:
-    /**
-     * \brief Constructor that intiliazes the graph on creation and set
-     * the connected components to 0
-     */
-    explicit graph(int n) : adj(n, vector()) { connected_components = 0; }
-
-    void addEdge(int, int);
-
-    /**
-     * \brief Function the calculates the connected compoents in the graph
-     * by performing the depth first search on graph
-     *
-     * @return connected_components total connected components in graph
-     */
-    int getConnectedComponents() {
-        depth_first_search();
-        return connected_components;
-    }
-};
 
+namespace graph {
 /**
- * \brief Function that add edge between two nodes or vertices of graph
+ * @brief Function that add edge between two nodes or vertices of graph
  *
- * @param u any node or vertex of graph
- * @param v any node or vertex of graph
+ * @param adj adjacency list of graph.
+ * @param u any node or vertex of graph.
+ * @param v any node or vertex of graph.
  */
-void graph::addEdge(int u, int v) {
-    adj[u - 1].push_back(v - 1);
-    adj[v - 1].push_back(u - 1);
+void addEdge(std::vector> *adj, int u, int v) {
+    (*adj)[u - 1].push_back(v - 1);
+    (*adj)[v - 1].push_back(u - 1);
 }
 
 /**
- * \brief Function that perfoms depth first search algorithm on graph
+ * @brief Utility function for depth first seach algorithm
+ * this function explores the vertex which is passed into.
+ *
+ * @param adj adjacency list of graph.
+ * @param u vertex or node to be explored.
+ * @param visited already visited vertices.
  */
-void graph::depth_first_search() {
-    int n = adj.size();
-    vector visited(n, false);
+void explore(const std::vector> *adj, int u,
+             std::vector *visited) {
+    (*visited)[u] = true;
+    for (auto v : (*adj)[u]) {
+        if (!(*visited)[v]) {
+            explore(adj, v, visited);
+        }
+    }
+}
+
+/**
+ * @brief Function that perfoms depth first search algorithm on graph
+ * and calculated the number of connected components.
+ *
+ * @param adj adjacency list of graph.
+ *
+ * @return connected_components number of connected components in graph.
+ */
+int getConnectedComponents(const std::vector> *adj) {
+    int n = adj->size();
+    int connected_components = 0;
+    std::vector visited(n, false);
 
     for (int i = 0; i < n; i++) {
         if (!visited[i]) {
-            explore(i, visited);
+            explore(adj, i, &visited);
             connected_components++;
         }
     }
+    return connected_components;
 }
-/**
- * \brief Utility function for depth first seach algorithm
- * this function explores the vertex which is passed into.
- *
- * @param u vertex or node to be explored
- * @param visited already visited vertex
- */
-void graph::explore(int u, vector &visited) {
-    visited[u] = true;
-    for (auto v : adj[u]) {
-        if (!visited[v]) {
-            explore(v, visited);
-        }
-    }
+}  // namespace graph
+
+/** Function to test the algorithm */
+void tests() {
+    std::cout << "Running predefined tests..." << std::endl;
+    std::cout << "Initiating Test 1..." << std::endl;
+    std::vector> adj1(9, std::vector());
+    graph::addEdge(&adj1, 1, 2);
+    graph::addEdge(&adj1, 1, 3);
+    graph::addEdge(&adj1, 3, 4);
+    graph::addEdge(&adj1, 5, 7);
+    graph::addEdge(&adj1, 5, 6);
+    graph::addEdge(&adj1, 8, 9);
+
+    assert(graph::getConnectedComponents(&adj1) == 3);
+    std::cout << "Test 1 Passed..." << std::endl;
+
+    std::cout << "Innitiating Test 2..." << std::endl;
+    std::vector> adj2(10, std::vector());
+    graph::addEdge(&adj2, 1, 2);
+    graph::addEdge(&adj2, 1, 3);
+    graph::addEdge(&adj2, 1, 4);
+    graph::addEdge(&adj2, 2, 3);
+    graph::addEdge(&adj2, 3, 4);
+    graph::addEdge(&adj2, 4, 8);
+    graph::addEdge(&adj2, 4, 10);
+    graph::addEdge(&adj2, 8, 10);
+    graph::addEdge(&adj2, 8, 9);
+    graph::addEdge(&adj2, 5, 7);
+    graph::addEdge(&adj2, 5, 6);
+    graph::addEdge(&adj2, 6, 7);
+
+    assert(graph::getConnectedComponents(&adj2) == 2);
+    std::cout << "Test 2 Passed..." << std::endl;
 }
 
 /** Main function */
 int main() {
-    /// creating a graph with 4 vertex
-    graph g(4);
+    /// running predefined tests
+    tests();
 
-    /// Adding edges between vertices
-    g.addEdge(1, 2);
-    g.addEdge(3, 2);
+    int vertices = int(), edges = int();
+    std::cout << "Enter the number of vertices : ";
+    std::cin >> vertices;
+    std::cout << "Enter the number of edges : ";
+    std::cin >> edges;
 
-    /// printing the connected components
-    std::cout << g.getConnectedComponents();
+    std::vector> adj(vertices, std::vector());
+
+    int u = int(), v = int();
+    while (edges--) {
+        std::cin >> u >> v;
+        graph::addEdge(&adj, u, v);
+    }
+
+    int cc = graph::getConnectedComponents(&adj);
+    std::cout << cc << std::endl;
     return 0;
 }