diff --git a/graph/is_graph_bipartite.cpp b/graph/is_graph_bipartite.cpp new file mode 100644 index 000000000..baadf71fa --- /dev/null +++ b/graph/is_graph_bipartite.cpp @@ -0,0 +1,163 @@ +/** + * @file + * + * @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. + * + * 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 + +/** + * @namespace graph + * @brief Graph algorithms + */ +namespace graph{ + /** + * @namespace is_graph_bipartite + * @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 + + 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; + } + } /// namespace is_graph_bipartite +} /// namespace graph +/** + * Function to test the above algorithm + * @returns none + */ +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::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); + 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"; + } +} +/** + * Main function + */ +int main(){ + test(); ///Testing + return 0; +} diff --git a/math/fibonacci.cpp b/math/fibonacci.cpp index e15cfc0cc..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) @@ -24,8 +24,40 @@ 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. + * @returns `void` +*/ +static void test() { + unsigned int test_case_1 = fibonacci(0); + assert(test_case_1 == 0); + std::cout << "Passed Test 1!" << std::endl; + + unsigned int test_case_2 = fibonacci(1); + assert(test_case_2 == 1); + std::cout << "Passed Test 2!" << std::endl; + + unsigned int test_case_3 = fibonacci(2); + assert(test_case_3 == 1); + std::cout << "Passed Test 3!" << std::endl; + + unsigned int test_case_4 = fibonacci(3); + assert(test_case_4 == 2); + std::cout << "Passed Test 4!" << std::endl; + + unsigned int test_case_5 = fibonacci(4); + assert(test_case_5 == 3); + std::cout << "Passed Test 5!" << std::endl; + + unsigned 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);