Number of paths from source to destination in a directed acyclic graph
Last Updated :
03 Jun, 2025
Given a Directed Acyclic Graph (DAG) with V
 nodes labeled from 0
 to V-1
, and a list of directed edges, count the total number of distinct paths from a given start
 node to a destination
 node. Each edge is represented as edges[i] = [u, v]
, indicating a directed edge from u
 to v
.
Examples:Â
Input: edges[][] = [[0,1], [0,3], [2,0], [2,1], [1,3]], V = 4, src = 2, dest = 3
Output: 3
Explanation: There are three ways to reach at 3 from 2. These are: 2 -> 1 -> 3, 2 -> 0 -> 3 and 2 -> 0 -> 1 -> 3.

Input: edges[][] = [[0,1], [1,2], [1,3], [2,3]], V = 4, src = 0, dest = 3
Output: 2
Explanation: There is two way to reach at 3 from 0 that is : 0 -> 1 -> 2 -> 3 and 0 -> 1 -> 3.
[Naive Approach] Using Depth First Search - O(2^n) time and O(n) space
The idea is to perform a Depth First Search traversal starting from the source node and count the number of paths reaching destination node.
Step by step approach:
- Create an adjacency list from the edges of the graph.
- Start DFS from the source node. For each node:
- If current node is destination node, return 1.
- Otherwise, for each edge from current node, find the number of paths for the adjacent node recursively and add it to the result.
C++
// C++ program to find Number of paths from source
// to destination in a directed acyclic graph
#include <bits/stdc++.h>
using namespace std;
int dfs(int u, int dest, vector<vector<int>> &adj) {
// If destination is reached
if (u == dest) return 1;
int count = 0;
// Count number of paths from current node
// to destination node.
for (int v : adj[u]) {
count += dfs(v, dest, adj);
}
return count;
}
int countPaths(vector<vector<int>>& edges, int V, int src, int dest) {
vector<vector<int>> adj(V);
for (auto e: edges) {
adj[e[0]].push_back(e[1]);
}
return dfs(src, dest, adj);
}
int main() {
int V = 4;
int src = 2, dest = 3;
vector<vector<int>> edges =
{{0,1}, {0,3}, {2,0}, {2,1}, {1,3}};
cout << countPaths(edges, V, src, dest);
return 0;
}
Java
// Java program to find Number of paths from source
// to destination in a directed acyclic graph
import java.util.ArrayList;
class GfG {
static int dfs(int u, int dest, ArrayList<ArrayList<Integer>> adj) {
// If destination is reached
if (u == dest) return 1;
int count = 0;
// Count number of paths from current node
// to destination node.
for (int v : adj.get(u)) {
count += dfs(v, dest, adj);
}
return count;
}
static int countPaths( int[][] edges, int V, int src, int dest) {
ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
for (int i = 0; i < V; i++) {
adj.add(new ArrayList<>());
}
for (int[] e : edges) {
adj.get(e[0]).add(e[1]);
}
return dfs(src, dest, adj);
}
public static void main(String[] args) {
int V = 4;
int src = 2, dest = 3;
int[][] edges =
{{0,1}, {0,3}, {2,0}, {2,1}, {1,3}};
System.out.println(countPaths(edges, V, src, dest));
}
}
Python
# Python program to find Number of paths from source
# to destination in a directed acyclic graph
def dfs(u, dest, adj):
# If destination is reached
if u == dest:
return 1
count = 0
# Count number of paths from current node
# to destination node.
for v in adj[u]:
count += dfs(v, dest, adj)
return count
def countPaths( edges, V, src, dest):
adj = [[] for _ in range(V)]
for e in edges:
adj[e[0]].append(e[1])
return dfs(src, dest, adj)
if __name__ == "__main__":
V = 4
src = 2
dest = 3
edges = [[0,1], [0,3], [2,0], [2,1], [1,3]]
print(countPaths(edges, V, src, dest))
C#
// C# program to find Number of paths from source
// to destination in a directed acyclic graph
using System;
using System.Collections.Generic;
class GfG {
static int Dfs(int u, int dest, List<List<int>> adj) {
// If destination is reached
if (u == dest) return 1;
int count = 0;
// Count number of paths from current node
// to destination node.
foreach (int v in adj[u]) {
count += Dfs(v, dest, adj);
}
return count;
}
static int CountPaths(int[,] edges, int V, int src, int dest) {
List<List<int>> adj = new List<List<int>>();
for (int i = 0; i < V; i++) {
adj.Add(new List<int>());
}
for (int i = 0; i < edges.GetLength(0); i++) {
adj[edges[i, 0]].Add(edges[i, 1]);
}
return Dfs(src, dest, adj);
}
static void Main() {
int V = 4;
int src = 2, dest = 3;
int[,] edges =
{{0,1}, {0,3}, {2,0}, {2,1}, {1,3}};
Console.WriteLine(CountPaths(edges, V, src, dest));
}
}
JavaScript
// JavaScript program to find Number of paths from source
// to destination in a directed acyclic graph
function dfs(u, dest, adj) {
// If destination is reached
if (u === dest) return 1;
let count = 0;
// Count number of paths from current node
// to destination node.
for (const v of adj[u]) {
count += dfs(v, dest, adj);
}
return count;
}
function countPaths(edges, V, src, dest) {
const adj = Array.from({ length: V }, () => []);
for (const e of edges) {
adj[e[0]].push(e[1]);
}
return dfs(src, dest, adj);
}
const V = 4;
const src = 2, dest = 3;
const edges =
[[0,1], [0,3], [2,0], [2,1], [1,3]];
console.log(countPaths(edges, V, src, dest));
[Expected Approach - 1] Using DFS + DP - O(V + E) time and O(V) space
The idea is to avoid re-computation of subproblems by storing the number of paths from each node to the destination in a memoization array.
In the above approach, we can observe that the number of paths from certain nodes is calculated multiple times. In example 1, the number of paths from Node 3 is calculated twice due to edges from 0 and 2. As graph is directed acyclic graph, so the number of paths from each node will remain same for any number of times. So, we can simply compute the result and memoize it.
Below is the recurrence relation:
numberOfPaths(u) = SUM( numberOfPaths(v) ), for each node v such that there exists an edge from u to v.
Base Case:
- numberOfPaths(u) = 1, if u is equal to destination node.
Step by step approach:
- Create an adjacency list from the edges.
- Start Depth First Search from the source node. For each node:
- Return 1, if the node is the destination node.
- If the number of paths for this node is already computed, return the memoized value.
- Otherwise:
- For each edge from current node, find the number of paths for the adjacent node recursively and add it to the result.
- Memoize this value and return it.
C++
// C++ program to find Number of paths from source
// to destination in a directed acyclic graph
#include <bits/stdc++.h>
using namespace std;
int dfs(int u, int dest, vector<vector<int>> &adj, vector<int> &memo) {
// If destination is reached
if (u == dest) return 1;
// If number of paths from this node
// is memoized
if (memo[u] != -1) return memo[u];
int count = 0;
for (int v : adj[u]) {
count += dfs(v, dest, adj, memo);
}
return memo[u] = count;
}
int countPaths( vector<vector<int>> &edges, int V, int src, int dest) {
vector<vector<int>> adj(V);
for (auto e: edges) {
adj[e[0]].push_back(e[1]);
}
vector<int> memo(V, -1);
return dfs(src, dest, adj, memo);
}
int main() {
int V = 4;
int src = 2, dest = 3;
vector<vector<int>> edges =
{{0,1}, {0,3}, {2,0}, {2,1}, {1,3}};
cout << countPaths(edges, V, src, dest);
return 0;
}
Java
// Java program to find Number of paths from source
// to destination in a directed acyclic graph
import java.util.ArrayList;
import java.util.Arrays;
class GfG {
static int dfs(int u, int dest,
ArrayList<ArrayList<Integer>> adj, int[] memo) {
// If destination is reached
if (u == dest) return 1;
// If number of paths from this node
// is memoized
if (memo[u] != -1) return memo[u];
int count = 0;
for (int v : adj.get(u)) {
count += dfs(v, dest, adj, memo);
}
return memo[u] = count;
}
static int countPaths( int[][] edges, int V, int src, int dest) {
ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
for (int i = 0; i < V; i++) {
adj.add(new ArrayList<>());
}
for (int[] e : edges) {
adj.get(e[0]).add(e[1]);
}
int[] memo = new int[V];
Arrays.fill(memo, -1);
return dfs(src, dest, adj, memo);
}
public static void main(String[] args) {
int V = 4;
int src = 2, dest = 3;
int[][] edges =
{{0,1}, {0,3}, {2,0}, {2,1}, {1,3}};
System.out.println(countPaths(edges, V, src, dest));
}
}
Python
# Python program to find Number of paths from source
# to destination in a directed acyclic graph
def dfs(u, dest, adj, memo):
# If destination is reached
if u == dest:
return 1
# If number of paths from this node
# is memoized
if memo[u] != -1:
return memo[u]
count = 0
for v in adj[u]:
count += dfs(v, dest, adj, memo)
memo[u] = count
return count
def countPaths(edges, V, src, dest):
adj = [[] for _ in range(V)]
for e in edges:
adj[e[0]].append(e[1])
memo = [-1] * V
return dfs(src, dest, adj, memo)
if __name__ == "__main__":
V = 4
src = 2
dest = 3
edges = [[0,1], [0,3], [2,0], [2,1], [1,3]]
print(countPaths(edges, V, src, dest))
C#
// C# program to find Number of paths from source
// to destination in a directed acyclic graph
using System;
using System.Collections.Generic;
class GfG {
static int Dfs(int u, int dest, List<List<int>> adj, int[] memo) {
// If destination is reached
if (u == dest) return 1;
// If number of paths from this node
// is memoized
if (memo[u] != -1) return memo[u];
int count = 0;
foreach (int v in adj[u]) {
count += Dfs(v, dest, adj, memo);
}
return memo[u] = count;
}
static int CountPaths(int[,] edges, int V, int src, int dest) {
List<List<int>> adj = new List<List<int>>();
for (int i = 0; i < V; i++) {
adj.Add(new List<int>());
}
for (int i = 0; i < edges.GetLength(0); i++) {
adj[edges[i, 0]].Add(edges[i, 1]);
}
int[] memo = new int[V];
Array.Fill(memo, -1);
return Dfs(src, dest, adj, memo);
}
static void Main() {
int V = 4;
int src = 2, dest = 3;
int[,] edges =
{{0,1}, {0,3}, {2,0}, {2,1}, {1,3}};
Console.WriteLine(CountPaths(edges, V, src, dest));
}
}
JavaScript
// JavaScript program to find Number of paths from source
// to destination in a directed acyclic graph
function dfs(u, dest, adj, memo) {
// If destination is reached
if (u === dest) return 1;
// If number of paths from this node
// is memoized
if (memo[u] !== -1) return memo[u];
let count = 0;
for (const v of adj[u]) {
count += dfs(v, dest, adj, memo);
}
return memo[u] = count;
}
function countPaths( edges, V, src, dest) {
const adj = Array.from({ length: V }, () => []);
for (const e of edges) {
adj[e[0]].push(e[1]);
}
const memo = new Array(V).fill(-1);
return dfs(src, dest, adj, memo);
}
const V = 4;
const src = 2, dest = 3;
const edges =
[[0,1], [0,3], [2,0], [2,1], [1,3]];
console.log(countPaths(edges, V, src, dest));
[Expected Approach - 2] Using DFS + Topological Sort - O(V + E) time and O(V) space
The idea is to process nodes in topological order so that all paths leading to a node are computed before using it to calculate paths for dependent nodes.
In this approach, we are calculating the number of paths for each node from the source node. At the end, we can simply return the number of paths from source to destination by returning the value at destination index.
Step by step approach:
- Create an adjacency list and compute in-degree for each node. Also, create an array of size V to store the number of paths for each node from source node.
- Set paths[source] = 1, as there is only one path from source to source.
- Perform topological sort using Kahn's algorithm. For each node in topological order:
- Add its number of paths to all its neighbors.
- If in-degree of any neighbor becomes 1, add it to queue.
- Return number of paths stored for the destination node.
C++
// C++ program to find Number of paths from source
// to destination in a directed acyclic graph
#include <bits/stdc++.h>
using namespace std;
int countPaths( vector<vector<int>> &edges, int V, int src, int dest) {
vector<vector<int>> adj(V);
vector<int> inDeg(V, 0);
// Create adjancecny list and
// find in-degree
for (auto e: edges) {
adj[e[0]].push_back(e[1]);
inDeg[e[1]]++;
}
queue<int> q;
for (int i = 0; i < V; i++) {
if (inDeg[i] == 0) q.push(i);
}
vector<int> paths(V, 0);
paths[src] = 1;
while (!q.empty()) {
int u = q.front(); q.pop();
// For each edge u->v, if number of
// paths starting from source node to
// u'th node is x, then the same paths
// will be present for v'th node.
for (int v : adj[u]) {
paths[v] += paths[u];
if (--inDeg[v] == 0) {
q.push(v);
}
}
}
return paths[dest];
}
int main() {
int V = 4;
int src = 2, dest = 3;
vector<vector<int>> edges =
{{0,1}, {0,3}, {2,0}, {2,1}, {1,3}};
cout << countPaths(edges, V, src, dest);
return 0;
}
Java
// Java program to find Number of paths from source
// to destination in a directed acyclic graph
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
class GfG {
static int countPaths(int[][] edges, int V, int src, int dest) {
ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
int[] inDeg = new int[V];
// Create adjancecny list and
// find in-degree
for (int i = 0; i < V; i++) {
adj.add(new ArrayList<>());
}
for (int[] e : edges) {
adj.get(e[0]).add(e[1]);
inDeg[e[1]]++;
}
Queue<Integer> q = new LinkedList<>();
for (int i = 0; i < V; i++) {
if (inDeg[i] == 0) q.add(i);
}
int[] paths = new int[V];
paths[src] = 1;
while (!q.isEmpty()) {
int u = q.poll();
// For each edge u->v, if number of
// paths starting from source node to
// u'th node is x, then the same paths
// will be present for v'th node.
for (int v : adj.get(u)) {
paths[v] += paths[u];
if (--inDeg[v] == 0) {
q.add(v);
}
}
}
return paths[dest];
}
public static void main(String[] args) {
int V = 4;
int src = 2, dest = 3;
int[][] edges =
{{0,1}, {0,3}, {2,0}, {2,1}, {1,3}};
System.out.println(countPaths(edges, V, src, dest));
}
}
Python
# Python program to find Number of paths from source
# to destination in a directed acyclic graph
from collections import deque
def countPaths(edges, V, src, dest):
adj = [[] for _ in range(V)]
inDeg = [0] * V
# Create adjancecny list and
# find in-degree
for e in edges:
adj[e[0]].append(e[1])
inDeg[e[1]] += 1
q = deque()
for i in range(V):
if inDeg[i] == 0:
q.append(i)
paths = [0] * V
paths[src] = 1
while q:
u = q.popleft()
# For each edge u->v, if number of
# paths starting from source node to
# u'th node is x, then the same paths
# will be present for v'th node.
for v in adj[u]:
paths[v] += paths[u]
inDeg[v] -= 1
if inDeg[v] == 0:
q.append(v)
return paths[dest]
if __name__ == "__main__":
V = 4
src = 2
dest = 3
edges = [[0,1], [0,3], [2,0], [2,1], [1,3]]
print(countPaths(edges, V, src, dest))
C#
// C# program to find Number of paths from source
// to destination in a directed acyclic graph
using System;
using System.Collections.Generic;
class GfG {
static int CountPaths(int[,] edges, int V, int src, int dest) {
List<List<int>> adj = new List<List<int>>();
int[] inDeg = new int[V];
// Create adjancecny list and
// find in-degree
for (int i = 0; i < V; i++) {
adj.Add(new List<int>());
}
for (int i = 0; i < edges.GetLength(0); i++) {
adj[edges[i, 0]].Add(edges[i, 1]);
inDeg[edges[i, 1]]++;
}
Queue<int> q = new Queue<int>();
for (int i = 0; i < V; i++) {
if (inDeg[i] == 0) q.Enqueue(i);
}
int[] paths = new int[V];
paths[src] = 1;
while (q.Count > 0) {
int u = q.Dequeue();
// For each edge u->v, if number of
// paths starting from source node to
// u'th node is x, then the same paths
// will be present for v'th node.
foreach (int v in adj[u]) {
paths[v] += paths[u];
if (--inDeg[v] == 0) {
q.Enqueue(v);
}
}
}
return paths[dest];
}
static void Main() {
int V = 4;
int src = 2, dest = 3;
int[,] edges =
{{0,1}, {0,3}, {2,0}, {2,1}, {1,3}};
Console.WriteLine(CountPaths(edges, V, src, dest));
}
}
JavaScript
// JavaScript program to find Number of paths from source
// to destination in a directed acyclic graph
function countPaths( edges, V, src, dest) {
const adj = Array.from({ length: V }, () => []);
const inDeg = new Array(V).fill(0);
// Create adjancecny list and
// find in-degree
for (const e of edges) {
adj[e[0]].push(e[1]);
inDeg[e[1]]++;
}
const q = [];
for (let i = 0; i < V; i++) {
if (inDeg[i] === 0) q.push(i);
}
const paths = new Array(V).fill(0);
paths[src] = 1;
while (q.length > 0) {
const u = q.shift();
// For each edge u->v, if number of
// paths starting from source node to
// u'th node is x, then the same paths
// will be present for v'th node.
for (const v of adj[u]) {
paths[v] += paths[u];
if (--inDeg[v] === 0) {
q.push(v);
}
}
}
return paths[dest];
}
const V = 4;
const src = 2, dest = 3;
const edges =
[[0,1], [0,3], [2,0], [2,1], [1,3]];
console.log(countPaths(edges, V, src, dest));
Similar Reads
Count of all unique paths from given source to destination in a Matrix Given a 2D matrix of size n*m, a source âsâ and a destination âdâ, print the count of all unique paths from given âsâ to âdâ. From each cell, you can either move only to the right or down. Examples: Input: arr[][] = { {1, 2, 3}, {4, 5, 6} }, s = {0, 0}, d = {1, 2}Output: 3Explanation: All possible p
4 min read
Number of shortest paths in an unweighted and directed graph Given an unweighted directed graph, can be cyclic or acyclic. Print the number of shortest paths from a given vertex to each of the vertices. For example consider the below graph. There is one shortest path vertex 0 to vertex 0 (from each vertex there is a single shortest path to itself), one shorte
11 min read
Number of distinct Shortest Paths from Node 1 to N in a Weighted and Directed Graph Given a directed and weighted graph of N nodes and M edges, the task is to count the number of shortest length paths between node 1 to N. Examples: Input: N = 4, M = 5, edges = {{1, 4, 5}, {1, 2, 4}, {2, 4, 5}, {1, 3, 2}, {3, 4, 3}}Output: 2Explanation: The number of shortest path from node 1 to nod
10 min read
Print all paths from a given source to a destination Given a directed acyclic graph, a source vertex src and a destination vertex dest, print all paths from given src to dest. Examples:Input: V = 4, edges[ ][ ] = [[0, 1], [1, 2], [1, 3], [2, 3]], src = 0, dest = 3Output: [[0, 1, 2, 3], [0, 1, 3]]Explanation: There are two ways to reach at 3 from 0. Th
12 min read
Minimum edges to reverse to make path from a source to a destination Given a directed graph with n nodes and m edges. A source node and a destination node are also given, we need to find how many edges we need to reverse in order to make at least 1 path from the source node to the destination node.Note: In case there is no way then return -1.Examples:  Input: n = 7,
15+ min read