@@ -32,27 +32,28 @@ namespace graph {
3232 * @returns the number of paths from node `u` to node `v`
3333 */
3434 std::uint32_t count_paths_dfs (const std::vector<std::vector<std::uint32_t >>& A,
35- std::uint32_t u,
36- std::uint32_t v,
37- std::uint32_t n,
38- std::vector<bool >& visited) {
35+ std::uint32_t u,
36+ std::uint32_t v,
37+ std::uint32_t n,
38+ std::vector<bool >& visited) {
3939 if (u == v) {
40- return 1 ; // Base case: Reached the destination node
40+ return 1 ; // Base case: Reached the destination node
4141 }
4242
43- visited[u] = true ; // Mark the current node as visited
44- std::uint32_t path_count = 0 ; // Count of all paths from `u` to `v`
43+ visited[u] = true ; // Mark the current node as visited
44+ std::uint32_t path_count = 0 ; // Count of all paths from `u` to `v`
4545
4646 for (std::uint32_t i = 0 ; i < n; i++) {
47- if (A[u][i] == 1 && !visited[i]) { // Check if there is an edge and the node is not visited
48- path_count += count_paths_dfs (A, i, v, n, visited); // Recursively explore paths from `i` to `v`
47+ if (A[u][i] == 1 && !visited[i]) { // Check if there is an edge and the node is not visited
48+ path_count += count_paths_dfs (A, i, v, n, visited); // Recursively explore paths from `i` to `v`
4949 }
5050 }
5151
52- visited[u] = false ; // Unmark the current node as visited (backtracking)
52+ visited[u] = false ; // Unmark the current node as visited (backtracking)
5353 return path_count;
5454 }
5555
56+
5657 /* *
5758 * @brief Counts the number of paths from node `u` to node `v` in a directed graph
5859 * using Depth First Search (DFS)
@@ -64,11 +65,16 @@ namespace graph {
6465 * @returns the number of paths from node `u` to node `v`
6566 */
6667 std::uint32_t count_paths (const std::vector<std::vector<std::uint32_t >>& A,
67- std::uint32_t u,
68- std::uint32_t v,
69- std::uint32_t n) {
70- std::vector<bool > visited (n, false ); // Initialize a visited vector for tracking nodes
71- return count_paths_dfs (A, u, v, n, visited);
68+ std::uint32_t u,
69+ std::uint32_t v,
70+ std::uint32_t n) {
71+ // Check for invalid nodes or empty graph
72+ if (u >= n || v >= n || A.empty () || A[0 ].empty ()) {
73+ return 0 ; // No valid paths if graph is empty or nodes are out of bounds
74+ }
75+
76+ std::vector<bool > visited (n, false ); // Initialize a visited vector for tracking nodes
77+ return count_paths_dfs (A, u, v, n, visited); // Start DFS
7278 }
7379
7480} // namespace graph
@@ -118,6 +124,20 @@ static void test() {
118124 std::uint32_t n4 = 1 , u4 = 0 , v4 = 0 ;
119125 assert (graph::count_paths (graph4, u4, v4, n4) == 1 ); // There is self-loop, so 1 path from node 0 to 0
120126
127+ // Test case 5: Empty graph (no nodes, no paths)
128+ std::vector<std::vector<std::uint32_t >> graph5 = {{}};
129+ int n5 = 0 , u5 = 0 , v5 = 0 ;
130+ assert (graph::count_paths (graph5, u5, v5, n5) == 0 ); // There are no paths in an empty graph
131+
132+ // Test case 6: Invalid nodes (out of bounds)
133+ std::vector<std::vector<std::uint32_t >> graph6 = {
134+ {0 , 1 , 0 },
135+ {0 , 0 , 1 },
136+ {0 , 0 , 0 }
137+ };
138+ int n6 = 3 , u6 = 0 , v6 = 5 ; // Node `v` is out of bounds (n = 3, so valid indices are 0, 1, 2)
139+ assert (graph::count_paths (graph6, u6, v6, n6) == 0 ); // Should return 0 because `v = 5` is invalid
140+
121141 std::cout << " All tests have successfully passed!\n " ;
122142}
123143
0 commit comments