2222namespace graph {
2323
2424 /* *
25- * @brief Counts the number of paths from node `u` to node `v` in a directed graph
26- * using Depth First Search (DFS)
27- *
25+ * @brief Helper function to perform DFS and count the number of paths from node `u` to node `v`
2826 * @param A adjacency matrix representing the graph (1: edge exists, 0: no edge)
2927 * @param u the starting node
3028 * @param v the destination node
3129 * @param n the number of nodes in the graph
30+ * @param visited a vector to keep track of visited nodes in the current DFS path
3231 * @returns the number of paths from node `u` to node `v`
3332 */
34- int count_paths (const std::vector<std::vector<int >> & A, int u, int v, int n) {
33+ int count_paths_dfs (const std::vector<std::vector<unsigned int >>& A, int u, int v, int n, std::vector< bool >& visited ) {
3534 if (u == v) {
3635 return 1 ; // Base case: Reached the destination node
3736 }
3837
38+ visited[u] = true ; // Mark the current node as visited
3939 int path_count = 0 ; // Count of all paths from `u` to `v`
4040
4141 for (int i = 0 ; i < n; i++) {
42- if (A[u][i] == 1 ) { // Check if there is an edge from `u` to `i`
43- path_count += count_paths (A, i, v, n); // Recursively explore paths from `i` to `v`
42+ if (A[u][i] == 1 && !visited[i] ) { // Check if there is an edge and the node is not visited
43+ path_count += count_paths_dfs (A, i, v, n, visited ); // Recursively explore paths from `i` to `v`
4444 }
4545 }
4646
47+ visited[u] = false ; // Unmark the current node as visited (backtracking)
4748 return path_count;
4849 }
4950
51+ /* *
52+ * @brief Counts the number of paths from node `u` to node `v` in a directed graph
53+ * using Depth First Search (DFS)
54+ *
55+ * @param A adjacency matrix representing the graph (1: edge exists, 0: no edge)
56+ * @param u the starting node
57+ * @param v the destination node
58+ * @param n the number of nodes in the graph
59+ * @returns the number of paths from node `u` to node `v`
60+ */
61+ int count_paths (const std::vector<std::vector<unsigned int >>& A, int u, int v, int n) {
62+ std::vector<bool > visited (n, false ); // Initialize a visited vector for tracking nodes
63+ return count_paths_dfs (A, u, v, n, visited);
64+ }
65+
5066} // namespace graph
5167
5268/* *
@@ -55,7 +71,7 @@ namespace graph {
5571 */
5672static void test () {
5773 // Test case 1: Simple directed graph with multiple paths
58- std::vector<std::vector<int >> graph1 = {
74+ std::vector<std::vector<unsigned int >> graph1 = {
5975 {0 , 1 , 0 , 1 , 0 },
6076 {0 , 0 , 1 , 0 , 1 },
6177 {0 , 0 , 0 , 0 , 1 },
@@ -64,10 +80,39 @@ static void test() {
6480 };
6581 int n1 = 5 , u1 = 0 , v1 = 4 ;
6682 assert (graph::count_paths (graph1, u1, v1, n1) == 3 ); // There are 3 paths from node 0 to 4
83+
84+ // Test case 2: No possible path (disconnected graph)
85+ std::vector<std::vector<unsigned int >> graph2 = {
86+ {0 , 1 , 0 , 0 , 0 },
87+ {0 , 0 , 0 , 0 , 0 },
88+ {0 , 0 , 0 , 0 , 1 },
89+ {0 , 0 , 1 , 0 , 0 },
90+ {0 , 0 , 0 , 0 , 0 }
91+ };
92+ int n2 = 5 , u2 = 0 , v2 = 4 ;
93+ assert (graph::count_paths (graph2, u2, v2, n2) == 0 ); // No path from node 0 to 4
94+
95+ // Test case 3: Cyclic graph with multiple paths
96+ std::vector<std::vector<unsigned int >> graph3 = {
97+ {0 , 1 , 0 , 0 , 0 },
98+ {0 , 0 , 1 , 1 , 0 },
99+ {1 , 0 , 0 , 0 , 1 },
100+ {0 , 0 , 1 , 0 , 1 },
101+ {0 , 0 , 0 , 0 , 0 }
102+ };
103+ int n3 = 5 , u3 = 0 , v3 = 4 ;
104+ assert (graph::count_paths (graph3, u3, v3, n3) == 3 ); // There are 3 paths from node 0 to 4
105+
106+ // Test case 4: Single node graph (self-loop)
107+ std::vector<std::vector<unsigned int >> graph4 = {
108+ {0 }
109+ };
110+ int n4 = 1 , u4 = 0 , v4 = 0 ;
111+ assert (graph::count_paths (graph4, u4, v4, n4) == 1 ); // There is self-loop, so 1 path from node 0 to 0
112+
67113 std::cout << " All tests have successfully passed!\n " ;
68114}
69115
70-
71116/* *
72117 * @brief Main function
73118 * @returns 0 on exit
0 commit comments