05. Count the paths
β GFG solution to Count Paths in DAG problem: count total distinct paths from source to destination in a directed acyclic graph using topological sorting and DP. π
The problem can be found at the following link: π Question Link
π§© Problem Description
Given a Directed Acyclic Graph (DAG) with V
nodes labeled from 0
to V-1
, and a list of directed edges edges[i] = [u, v]
representing a directed edge from node u
to node v
, find the total number of distinct paths from a given source node S
to a destination node D
.
π Examples
Example 1
Input: edges = [[0,1], [0,3], [2,0], [2,1], [1,3]], V = 4, S = 2, D = 3
Output: 3
Explanation: There are 3 ways to reach 3 from 2:
2 -> 1 -> 3,
2 -> 0 -> 3,
2 -> 0 -> 1 -> 3.
Example 2
Input: edges = [[0,1], [1,2], [1,3], [2,3]], V = 4, S = 0, D = 3
Output: 2
Explanation: There are 2 ways to reach 3 from 0:
0 -> 1 -> 2 -> 3,
0 -> 1 -> 3.
π Constraints
$2 \le V \le 10^3$
$1 \le E = \text{edges.size()} \le \frac{V \times (V - 1)}{2}$
β
My Approach
Topological Sort + Dynamic Programming (DP)
Idea:
Since the graph is a DAG (Directed Acyclic Graph), we can perform a topological sort to linearize the nodes in an order that respects dependencies (edges).
Build the adjacency list and an in-degree array (counts of incoming edges per node).
Use Kahnβs algorithm for topological sorting:
Initialize a queue with all nodes having zero in-degree.
Iteratively remove nodes from the queue, adding them to the topological order, and decrease in-degree of their neighbors.
Initialize a
dp
array wheredp[i]
= number of ways to reach the destinationD
from nodei
.Set
dp[D] = 1
(base case).
Iterate nodes in reverse topological order:
For each node
u
, sum the paths of all its neighborsv
:dp[u] += dp[v]
.
The answer is
dp[S]
β the number of ways from sourceS
to destinationD
.
π Time and Auxiliary Space Complexity
Expected Time Complexity: O(V + E), since each node and edge is processed exactly once during topological sort and DP calculation.
Expected Auxiliary Space Complexity: O(V + E), required for adjacency list, in-degree array, DP array, and queue.
π§βπ» Code (C++)
class Solution {
public:
int countPaths(vector<vector<int>>& E, int V, int S, int D) {
vector<vector<int>> G(V); vector<int> I(V);
for (auto& e : E) G[e[0]].push_back(e[1]), I[e[1]]++;
queue<int> Q; for (int i = 0; i < V; i++) if (!I[i]) Q.push(i);
vector<int> T, dp(V); dp[D] = 1;
while (!Q.empty()) {
int u = Q.front(); Q.pop(); T.push_back(u);
for (int v : G[u]) if (--I[v] == 0) Q.push(v);
}
for (int i = V - 1; i >= 0; i--)
for (int v : G[T[i]]) dp[T[i]] += dp[v];
return dp[S];
}
};
π§βπ» Code (Java)
class Solution {
public int countPaths(int[][] E, int V, int S, int D) {
List<List<Integer>> G = new ArrayList<>();
int[] I = new int[V], dp = new int[V];
for (int i = 0; i < V; i++) G.add(new ArrayList<>());
for (int[] e : E) {
G.get(e[0]).add(e[1]);
I[e[1]]++;
}
Queue<Integer> Q = new ArrayDeque<>();
for (int i = 0; i < V; i++) if (I[i] == 0) Q.add(i);
List<Integer> T = new ArrayList<>();
while (!Q.isEmpty()) {
int u = Q.poll(); T.add(u);
for (int v : G.get(u)) if (--I[v] == 0) Q.add(v);
}
dp[D] = 1;
for (int i = V - 1; i >= 0; i--)
for (int v : G.get(T.get(i))) dp[T.get(i)] += dp[v];
return dp[S];
}
}
π Code (Python)
class Solution:
def countPaths(self, E, V, S, D):
from collections import defaultdict, deque
G = defaultdict(list); I = [0] * V
for u, v in E: G[u].append(v); I[v] += 1
Q = deque(i for i in range(V) if I[i] == 0)
T, dp = [], [0] * V; dp[D] = 1
while Q:
u = Q.popleft(); T.append(u)
for v in G[u]:
I[v] -= 1
if I[v] == 0: Q.append(v)
for u in reversed(T):
for v in G[u]: dp[u] += dp[v]
return dp[S]
π§ Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: π¬ Any Questions?. Letβs make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated