From 1f55da944474bc67ef5db27c2c783dd1784a0fe2 Mon Sep 17 00:00:00 2001 From: Anmol3299 Date: Sat, 30 May 2020 01:49:13 +0530 Subject: [PATCH 1/9] feat: Modern trie code with better memory management --- data_structure/trie_modern.cpp | 156 +++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 data_structure/trie_modern.cpp diff --git a/data_structure/trie_modern.cpp b/data_structure/trie_modern.cpp new file mode 100644 index 000000000..0214969f0 --- /dev/null +++ b/data_structure/trie_modern.cpp @@ -0,0 +1,156 @@ +#include +#include // for std::shared_ptr<> +#include // for std::string class + +/** + * A basic implementation of trie class to store only lower-case strings. + * You can extend the implementation to all the ASCII characters by changing the + * value of @ ALPHABETS to 128. + */ +class Trie { + private: + static constexpr size_t ALPHABETS = 26; + + /** + * Structure of trie node. + * This struct doesn't need a constructor as we are initializing using + * intializer list which is more efficient than if we had done so with + * constructor. + */ + struct TrieNode { + // An array of pointers of size 26 which tells if a character of word is + // present or not. + std::shared_ptr character[ALPHABETS]{nullptr}; + + bool isEndOfWord{false}; + }; + + /** + * Function to check if a node has some children which can form words. + * @param node whose character array of pointers need to be checked for + * children. + * @return if a child is found, it returns @ true, else it returns @ false. + */ + inline static bool hasChildren(std::shared_ptr node) { + for (size_t i = 0; i < ALPHABETS; i++) { + if (node->character[i]) { + return true; + } + } + return false; + } + + /** + * A recursive helper function to remove a word from the trie. First, it + * recursively traverses to the location of last character of word in the + * trie. However, if the word is not found, the function returns a runtime + * error. Upon successfully reaching the last character of word in trie, if + * sets the isEndOfWord to false and deletes the node if and only if it has + * no children, else it returns the current node. + * @param word is the string which needs to be removed from trie. + * @param curr is the current node we are at. + * @param index is the index of the @word we are at. + * @return if current node has childern, it returns @ curr, else it returns + * nullptr. In case @ word is not found in the trie, the program stops and + * gives a runtime error. + */ + std::shared_ptr removeWordHelper(const std::string& word, + std::shared_ptr curr, + size_t index) { + if (word.size() == index) { + if (curr->isEndOfWord) { + curr->isEndOfWord = false; + } + if (hasChildren(curr)) { + return curr; + } + return nullptr; + } + + size_t idx = word[index] - 'a'; + + // Throw a runtime error in case the user enters a word which is not + // present in the trie. + if (!curr->character[idx]) { + throw std::runtime_error(std::move(std::string("Word not found."))); + } + + curr->character[idx] = + removeWordHelper(word, curr->character[idx], index + 1); + + // This if condition checks if the node has some childern. + // The 1st if check, i.e. (curr->character[idx]) is checked specifically + // because if the older string is a prefix of some other string, then, + // there would be no need to check all 26 characters. Example- str1 = + // abbey, str2 = abbex and we want to delete string "abbey", then in + // this case, there would be no need to check all characters for the + // chars a,b,b. + if (curr->character[idx] || hasChildren(curr)) { + return curr; + } + return nullptr; + } + + public: + // constructor to initialise the root of the trie. + Trie() : m_root(std::make_shared()){}; + + /** + * Insert a word into the trie. + * @param word which needs to be inserted into the string. + */ + void insert(const std::string& word) { + auto curr = m_root; + for (char ch : word) { + size_t index = ch - 'a'; + + // if a node for current word is not already present in trie, create + // a new node for it. + if (!curr->character[index]) { + curr->character[index] = std::make_shared(); + } + + curr = curr->character[index]; + } + curr->isEndOfWord = true; + } + + /** + * Search if a word is present in trie or not. + * @param word which is needed to be searched in the trie. + * @return if the word is found in the trie and isEndOfWord is set to true, + * then it returns @ true, else it returns @ false. + */ + bool search(const std::string& word) { + auto curr = m_root; + for (char ch : word) { + size_t index = ch - 'a'; + + // if any node for a character is not found, then return that the + // word cannot be formed. + if (!curr->character[index]) { + return false; + } + curr = curr->character[index]; + } + return curr->isEndOfWord; + } + + // Function to remove the word which calls the helper function. + void removeWord(const std::string& word) { + m_root = removeWordHelper(word, m_root, 0); + } + + private: + std::shared_ptr m_root; +}; + +int main() { + Trie trie; + trie.insert("hel"); + trie.insert("hello"); + trie.removeWord("hel"); + std::cout << trie.search("hello") << '\n'; + + return 0; +} From 517f71a2dd8c214a31495761ff0b5dd548838e16 Mon Sep 17 00:00:00 2001 From: Anmol3299 Date: Sat, 30 May 2020 01:57:16 +0530 Subject: [PATCH 2/9] minor fix to code style --- data_structure/trie_modern.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structure/trie_modern.cpp b/data_structure/trie_modern.cpp index 0214969f0..098ba1bb9 100644 --- a/data_structure/trie_modern.cpp +++ b/data_structure/trie_modern.cpp @@ -93,7 +93,7 @@ class Trie { public: // constructor to initialise the root of the trie. - Trie() : m_root(std::make_shared()){}; + Trie() : m_root(std::make_shared()) {} /** * Insert a word into the trie. From 0101f0ce2877b725fafc90f9949a1e9dd6e472c6 Mon Sep 17 00:00:00 2001 From: Anmol3299 Date: Sat, 30 May 2020 02:24:14 +0530 Subject: [PATCH 3/9] Add copyright header and improve comments --- data_structure/trie_modern.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/data_structure/trie_modern.cpp b/data_structure/trie_modern.cpp index 098ba1bb9..218c90b68 100644 --- a/data_structure/trie_modern.cpp +++ b/data_structure/trie_modern.cpp @@ -1,6 +1,12 @@ -#include -#include // for std::shared_ptr<> -#include // for std::string class +/** + * Copyright 2020 @author Anmol3299 + * @file + * + * A basic implementation of trie class to store only lower-case strings. + */ +#include // for io operations +#include // for std::shared_ptr<> +#include // for std::string class /** * A basic implementation of trie class to store only lower-case strings. @@ -51,8 +57,8 @@ class Trie { * @param curr is the current node we are at. * @param index is the index of the @word we are at. * @return if current node has childern, it returns @ curr, else it returns - * nullptr. In case @ word is not found in the trie, the program stops and - * gives a runtime error. + * nullptr. + * @throw a runtime error in case @ word is not found in the trie. */ std::shared_ptr removeWordHelper(const std::string& word, std::shared_ptr curr, @@ -118,8 +124,9 @@ class Trie { /** * Search if a word is present in trie or not. * @param word which is needed to be searched in the trie. - * @return if the word is found in the trie and isEndOfWord is set to true, - * then it returns @ true, else it returns @ false. + * @return True if the word is found in trie and isEndOfWord is set to true. + * @return False if word is not found in trie or isEndOfWord is set to + * false. */ bool search(const std::string& word) { auto curr = m_root; @@ -142,9 +149,13 @@ class Trie { } private: + // data member to store the root of the trie. std::shared_ptr m_root; }; +/** + * Main function + */ int main() { Trie trie; trie.insert("hel"); From 09af5e3c0e6ff6575ee747c89f480c7f85945546 Mon Sep 17 00:00:00 2001 From: Anmol3299 Date: Tue, 2 Jun 2020 21:36:31 +0530 Subject: [PATCH 4/9] feat: Add BFS and DFS algorithms to check for cycle in a directed graph --- graph/cycle_check_directed_graph.cpp | 322 +++++++++++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 graph/cycle_check_directed_graph.cpp diff --git a/graph/cycle_check_directed_graph.cpp b/graph/cycle_check_directed_graph.cpp new file mode 100644 index 000000000..0cf5ac28e --- /dev/null +++ b/graph/cycle_check_directed_graph.cpp @@ -0,0 +1,322 @@ +/** + * Copyright 2020 + * @file cycle_check_directed graph.cpp + * + * @brief BFS and DFS algorithms to check for cycle in a directed graph. + * + * @author Anmol3299 + * contact: mittalanmol22@gmail.com + * + */ + +#include // for std::cout +#include // for std::queue +#include // for throwing errors +#include // for std::remove_reference_t +#include // for std::unordered_map +#include // for std::move +#include // for std::vector + +/** + * Implementation of non-weighted directed edge of a graph. + * + * The source vertex of the edge is labelled "src" and destination vertex is + * labelled "dest". + */ +struct Edge { + unsigned int src; + unsigned int dest; + + Edge() = delete; + ~Edge() = default; + Edge(Edge&&) = default; + Edge& operator=(Edge&&) = default; + Edge(Edge const&) = default; + Edge& operator=(Edge const&) = default; + + /** Set the source and destination of the vertex. + * + * @param source is the source vertex of the edge. + * @param destination is the destination vertex of the edge. + */ + Edge(unsigned int const& source, unsigned int const& destination) + : src(source), dest(destination) {} +}; + +using AdjList = std::unordered_map>; + +/** + * Implementation of graph class. + * + * The graph will be represented using Adjacency List representation. + * This class contains 2 data members "m_vertices" & "m_adjList" used to + * represent the number of vertices and adjacency list of the graph + * respectively. The vertices are labelled 0 - (m_vertices - 1). + */ +class Graph { + public: + Graph() : m_vertices(0), m_adjList({}) {} + ~Graph() = default; + Graph(Graph&&) = default; + Graph& operator=(Graph&&) = default; + Graph(Graph const&) = default; + Graph& operator=(Graph const&) = default; + + /** Create a graph from vertices and adjacency list. + * + * @param vertices specify the number of vertices the graph would contain. + * @param adjList is the adjacency list representation of graph. + */ + Graph(unsigned int const& vertices, AdjList const& adjList) + : m_vertices(vertices), m_adjList(adjList) {} + + /** Create a graph from vertices and adjacency list. + * + * @param vertices specify the number of vertices the graph would contain. + * @param adjList is the adjacency list representation of graph. + */ + Graph(unsigned int const& vertices, AdjList&& adjList) + : m_vertices(std::move(vertices)), m_adjList(std::move(adjList)) {} + + /** Create a graph from vertices and a set of edges. + * + * Adjacency list of the graph would be created from the set of edges. If + * the source or destination of any edge has a value greater or equal to + * number of vertices, then it would throw a range_error. + * + * @param vertices specify the number of vertices the graph would contain. + * @param edges is a vector of edges. + */ + Graph(unsigned int const& vertices, std::vector const& edges) + : m_vertices(vertices) { + for (auto const& edge : edges) { + if (edge.src >= vertices || edge.dest >= vertices) { + throw std::range_error( + "Either src or dest of edge out of range"); + } + m_adjList[edge.src].emplace_back(edge.dest); + } + } + + /** Create a graph from vertices and a set of edges. + * + * Adjacency list of the graph would be created from the set of edges. If + * the source or destination of any edge has a value greater or equal to + * number of vertices, then it would throw a range_error. + * + * @param vertices specify the number of vertices the graph would contain. + * @param edges is a vector of edges. + */ + Graph(unsigned int const& vertices, std::vector&& edges) + : m_vertices(vertices) { + for (auto&& edge : std::move(edges)) { + if (edge.src >= vertices || edge.dest >= vertices) { + throw std::range_error( + "Either src or dest of edge out of range"); + } + m_adjList[edge.src].emplace_back(std::move(edge.dest)); + } + } + + /** Return a const reference of the adjacency list. + * + * @return const reference to the adjacency list + */ + std::remove_reference_t const& getAdjList() const { + return m_adjList; + } + + /** + * @return number of vertices in the graph. + */ + std::remove_reference_t const& getVertices() const { + return m_vertices; + } + + /** Add vertices in the graph. + * + * @param num is the number of vertices to be added. It adds 1 vertex by + * default. + * + */ + void addVertices(unsigned int num = 1) { m_vertices += num; } + + /** Add an edge in the graph. + * + * @param edge that needs to be added. + */ + void addEdge(Edge const& edge) { + if (edge.src >= m_vertices || edge.dest >= m_vertices) { + throw std::range_error("Either src or dest of edge out of range"); + } + m_adjList[edge.src].emplace_back(edge.dest); + } + + /** Add an Edge in the graph + * + * @param source is source vertex of the edge. + * @param destination is the destination vertex of the edge. + */ + void addEdge(unsigned int const& source, unsigned int const& destination) { + if (source >= m_vertices || destination >= m_vertices) { + throw std::range_error( + "Either source or destination of edge out of range"); + } + m_adjList[source].emplace_back(destination); + } + + private: + unsigned int m_vertices; + AdjList m_adjList; +}; + +class CycleCheck { + private: + enum nodeStates : uint8_t { not_visited = 0, in_stack, visited }; + + /** Helper function of "isCyclicDFS". + * + * @param adjList is the adjacency list representation of some graph. + * @param state is the state of the nodes of the graph. + * @param node is the node being evaluated. + * + * @return true if graph has a cycle, else false. + */ + static bool isCyclicDFSHelper(AdjList const& adjList, + std::vector& state, + unsigned int node) { + // Add node "in_stack" state. + state[node] = in_stack; + + // If the node has children, then recursively visit all children of the + // node. + if (auto const& it = adjList.find(node); it != adjList.end()) { + for (auto child : it->second) { + // If state of child node is "not_visited", evaluate that child + // for presence of cycle. + if (auto state_of_child = state[child]; + state_of_child == not_visited) { + if (isCyclicDFSHelper(adjList, state, child)) { + return true; + } + } else if (state_of_child == in_stack) { + // If child node was "in_stack", then that means that there + // is a cycle in the graph. Return true for presence of the + // cycle. + return true; + } + } + } + + // Current node has been evaluated for the presence of cycle and had no + // cycle. Mark current node as "visited". + state[node] = visited; + // Return that current node didn't result in any cycles. + return false; + } + + public: + /** Driver function to check if a graph has a cycle. + * + * This function uses DFS to check for cycle in the graph. + * + * @param graph which needs to be evaluated for the presence of cycle. + * @return true if a cycle is detected, else false. + */ + static bool isCyclicDFS(Graph const& graph) { + /** State of the node. + * + * It is a vector of "nodeStates" which represents the state node is in. + * It can take only 3 values: "not_visited", "in_stack", and "visited". + * + * Initially, all nodes are in "not_visited" state. + */ + std::vector state(graph.getVertices(), not_visited); + + // Start visiting each node. + for (auto node = 0; node < graph.getVertices(); node++) { + // If a node is not visited, only then check for presence of cycle. + // There is no need to check for presence of cycle for a visited + // node as it has already been checked for presence of cycle. + if (state[node] == not_visited) { + // Check for cycle. + if (isCyclicDFSHelper(graph.getAdjList(), state, node)) { + return true; + } + } + } + + // All nodes have been safely traversed, that means there is no cycle in + // the graph. Return false. + return false; + } + + /** Check if a graph has cycle or not. + * + * This function uses BFS to check if a graph is cyclic or not. + * + * @param graph which needs to be evaluated for the presence of cycle. + * @return true if a cycle is detected, else false. + */ + static bool isCyclicBFS(Graph const& graph) { + AdjList graphAjdList = graph.getAdjList(); + + std::vector indegree(graph.getVertices(), 0); + // Calculate the indegree i.e. the number of incident edges to the node. + for (auto const& [parent, children] : graphAjdList) { + for (auto const& child : children) { + indegree[child]++; + } + } + + std::queue can_be_solved; + for (auto node = 0; node < graph.getVertices(); node++) { + // If a node doesn't have any input edges, then that node will + // definately not result in a cycle and can be visited safely. + if (!indegree[node]) { + can_be_solved.emplace(node); + } + } + + // Vertices that need to be traversed. + auto remain = graph.getVertices(); + // While there are safe nodes that we can visit. + while (!can_be_solved.empty()) { + auto front = can_be_solved.front(); + // Visit the node. + can_be_solved.pop(); + // Decrease number of nodes that need to be traversed. + remain--; + + // Visit all the children of the visited node. + if (auto it = graphAjdList.find(front); it != graphAjdList.end()) { + for (auto child : it->second) { + // Check if we can visited the node safely. + if (--indegree[child] == 0) { + // if node can be visited safely, then add that node to + // the visit queue. + can_be_solved.emplace(child); + } + } + } + } + + // If there are still nodes that we can't visit, then it means that + // there is a cycle and return true, else return false. + return !(remain == 0); + } +}; + +/** + * Main function. + */ +int main() { + // Instantiate the graph. + Graph g(7, {{0, 1}, {1, 2}, {2, 0}, {2, 5}, {3, 5}}); + // Check for cycle using BFS method. + std::cout << CycleCheck::isCyclicBFS(g) << '\n'; + + // Check for cycle using DFS method. + std::cout << CycleCheck::isCyclicDFS(g) << '\n'; + return 0; +} From c1fadaaeb39d52f0c64e53240b531daaaf355729 Mon Sep 17 00:00:00 2001 From: Anmol3299 Date: Wed, 3 Jun 2020 18:17:05 +0530 Subject: [PATCH 5/9] Remove const references for input of simple types Reason: overhead on access --- graph/cycle_check_directed_graph.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/graph/cycle_check_directed_graph.cpp b/graph/cycle_check_directed_graph.cpp index 0cf5ac28e..ba31b15c4 100644 --- a/graph/cycle_check_directed_graph.cpp +++ b/graph/cycle_check_directed_graph.cpp @@ -39,7 +39,7 @@ struct Edge { * @param source is the source vertex of the edge. * @param destination is the destination vertex of the edge. */ - Edge(unsigned int const& source, unsigned int const& destination) + Edge(unsigned int source, unsigned int destination) : src(source), dest(destination) {} }; @@ -67,7 +67,7 @@ class Graph { * @param vertices specify the number of vertices the graph would contain. * @param adjList is the adjacency list representation of graph. */ - Graph(unsigned int const& vertices, AdjList const& adjList) + Graph(unsigned int vertices, AdjList const& adjList) : m_vertices(vertices), m_adjList(adjList) {} /** Create a graph from vertices and adjacency list. @@ -75,7 +75,7 @@ class Graph { * @param vertices specify the number of vertices the graph would contain. * @param adjList is the adjacency list representation of graph. */ - Graph(unsigned int const& vertices, AdjList&& adjList) + Graph(unsigned int vertices, AdjList&& adjList) : m_vertices(std::move(vertices)), m_adjList(std::move(adjList)) {} /** Create a graph from vertices and a set of edges. @@ -87,7 +87,7 @@ class Graph { * @param vertices specify the number of vertices the graph would contain. * @param edges is a vector of edges. */ - Graph(unsigned int const& vertices, std::vector const& edges) + Graph(unsigned int vertices, std::vector const& edges) : m_vertices(vertices) { for (auto const& edge : edges) { if (edge.src >= vertices || edge.dest >= vertices) { @@ -107,7 +107,7 @@ class Graph { * @param vertices specify the number of vertices the graph would contain. * @param edges is a vector of edges. */ - Graph(unsigned int const& vertices, std::vector&& edges) + Graph(unsigned int vertices, std::vector&& edges) : m_vertices(vertices) { for (auto&& edge : std::move(edges)) { if (edge.src >= vertices || edge.dest >= vertices) { @@ -157,7 +157,7 @@ class Graph { * @param source is source vertex of the edge. * @param destination is the destination vertex of the edge. */ - void addEdge(unsigned int const& source, unsigned int const& destination) { + void addEdge(unsigned int source, unsigned int destination) { if (source >= m_vertices || destination >= m_vertices) { throw std::range_error( "Either source or destination of edge out of range"); From a3df421e36d4d6da66c1d116d184b7007e30ea57 Mon Sep 17 00:00:00 2001 From: Anmol3299 Date: Wed, 3 Jun 2020 18:53:01 +0530 Subject: [PATCH 6/9] fix bad code sorry for force push --- graph/cycle_check_directed_graph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graph/cycle_check_directed_graph.cpp b/graph/cycle_check_directed_graph.cpp index ba31b15c4..0aebd3c2e 100644 --- a/graph/cycle_check_directed_graph.cpp +++ b/graph/cycle_check_directed_graph.cpp @@ -109,7 +109,7 @@ class Graph { */ Graph(unsigned int vertices, std::vector&& edges) : m_vertices(vertices) { - for (auto&& edge : std::move(edges)) { + for (auto&& edge : edges) { if (edge.src >= vertices || edge.dest >= vertices) { throw std::range_error( "Either src or dest of edge out of range"); From a77dafba6466222040c268851279f6ce1de2f558 Mon Sep 17 00:00:00 2001 From: Anmol3299 Date: Wed, 3 Jun 2020 19:40:51 +0530 Subject: [PATCH 7/9] Use pointer instead of the non-const reference because apparently google says so. --- graph/cycle_check_directed_graph.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/graph/cycle_check_directed_graph.cpp b/graph/cycle_check_directed_graph.cpp index 0aebd3c2e..cfc5f2b02 100644 --- a/graph/cycle_check_directed_graph.cpp +++ b/graph/cycle_check_directed_graph.cpp @@ -183,10 +183,10 @@ class CycleCheck { * @return true if graph has a cycle, else false. */ static bool isCyclicDFSHelper(AdjList const& adjList, - std::vector& state, + std::vector* state, unsigned int node) { // Add node "in_stack" state. - state[node] = in_stack; + (*state)[node] = in_stack; // If the node has children, then recursively visit all children of the // node. @@ -194,7 +194,7 @@ class CycleCheck { for (auto child : it->second) { // If state of child node is "not_visited", evaluate that child // for presence of cycle. - if (auto state_of_child = state[child]; + if (auto state_of_child = (*state)[child]; state_of_child == not_visited) { if (isCyclicDFSHelper(adjList, state, child)) { return true; @@ -210,7 +210,7 @@ class CycleCheck { // Current node has been evaluated for the presence of cycle and had no // cycle. Mark current node as "visited". - state[node] = visited; + (*state)[node] = visited; // Return that current node didn't result in any cycles. return false; } @@ -240,7 +240,7 @@ class CycleCheck { // node as it has already been checked for presence of cycle. if (state[node] == not_visited) { // Check for cycle. - if (isCyclicDFSHelper(graph.getAdjList(), state, node)) { + if (isCyclicDFSHelper(graph.getAdjList(), &state, node)) { return true; } } From 8f04ffe3fb36334f3be63c40104db34c8df6ca24 Mon Sep 17 00:00:00 2001 From: Anmol3299 Date: Wed, 3 Jun 2020 20:33:38 +0530 Subject: [PATCH 8/9] Remove a useless and possibly bad Graph constuctor overload --- graph/cycle_check_directed_graph.cpp | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/graph/cycle_check_directed_graph.cpp b/graph/cycle_check_directed_graph.cpp index cfc5f2b02..4a619850d 100644 --- a/graph/cycle_check_directed_graph.cpp +++ b/graph/cycle_check_directed_graph.cpp @@ -98,26 +98,6 @@ class Graph { } } - /** Create a graph from vertices and a set of edges. - * - * Adjacency list of the graph would be created from the set of edges. If - * the source or destination of any edge has a value greater or equal to - * number of vertices, then it would throw a range_error. - * - * @param vertices specify the number of vertices the graph would contain. - * @param edges is a vector of edges. - */ - Graph(unsigned int vertices, std::vector&& edges) - : m_vertices(vertices) { - for (auto&& edge : edges) { - if (edge.src >= vertices || edge.dest >= vertices) { - throw std::range_error( - "Either src or dest of edge out of range"); - } - m_adjList[edge.src].emplace_back(std::move(edge.dest)); - } - } - /** Return a const reference of the adjacency list. * * @return const reference to the adjacency list From 9d8736e79e435ef7c0208bbdb91e99fa56bd681d Mon Sep 17 00:00:00 2001 From: Anmol3299 Date: Wed, 3 Jun 2020 20:40:09 +0530 Subject: [PATCH 9/9] Explicitely specify type of vector during graph instantiation --- graph/cycle_check_directed_graph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graph/cycle_check_directed_graph.cpp b/graph/cycle_check_directed_graph.cpp index 4a619850d..0f7b84cd3 100644 --- a/graph/cycle_check_directed_graph.cpp +++ b/graph/cycle_check_directed_graph.cpp @@ -292,7 +292,7 @@ class CycleCheck { */ int main() { // Instantiate the graph. - Graph g(7, {{0, 1}, {1, 2}, {2, 0}, {2, 5}, {3, 5}}); + Graph g(7, std::vector{{0, 1}, {1, 2}, {2, 0}, {2, 5}, {3, 5}}); // Check for cycle using BFS method. std::cout << CycleCheck::isCyclicBFS(g) << '\n';