Count all possible walks from a source to a destination with exactly k edges (original) (raw)

Last Updated : 12 Jun, 2025

Given a **directed graph and two vertices src and dest, the task is to count all possible walks from vertex **src to vertex **dest that consist of exactly **k edges.
The graph is represented using an adjacency matrix **adj[][], where **adj[i][j] = 1 indicates the presence of a directed edge from vertex **i to vertex **j, and **adj[i][j] = 0 indicates no edge from **i to **j.

**Example:

**Input: adj[][] = [[0, 1, 1, 1],
[0, 0, 0, 1],
[0, 0, 0, 1],
[0, 0, 0, 0]]
src = 0, dest = 3, k = 2

graph

**Output: 2
**Explanation: There are two walks from src (0) to dest (3) with exactly 2 edges: (0 → 1 → 3) and (0 → 2 → 3).

Try It Yourselfredirect icon

Table of Content

[Brute-Force Approach] Using Recursion - O(v^k) Time and O(k) Space

The idea is to **recursively explore all possible walks from **src to **dest using exactly **k edges. The thought process is that from the **current node, we try all its **adjacent neighbors and reduce **k by 1 in each recursive call. If **k becomes 0, we check whether we’ve reached the **destination — if yes, that’s a valid walk.

C++ `

// C++ Code to count walks from src to dest // with exactly k edges using recursion #include #include using namespace std;

// Function to count all walks from src to dest // using exactly k edges int countWalks(vector<vector> &adj, int src, int dest, int k) {

// Base Case: If k is 0 and src is same as dest
if (k == 0 && src == dest) {
    return 1;
}

// If k is 0 and src is not dest, no walk possible
if (k == 0) {
    return 0;
}

int count = 0;

// Try all adjacent vertices from src
for (int i = 0; i < adj.size(); i++) {

    // If there is an edge from src to i
    if (adj[src][i] == 1) {

        // Recur for the remaining k-1 edges
        count += countWalks(adj, i, dest, k - 1);
    }
}

return count;

}

int main() {

vector<vector<int>> adj = {
    {0, 1, 1, 1},
    {0, 0, 0, 1},
    {0, 0, 0, 1},
    {0, 0, 0, 0}
};

int src = 0, dest = 3, k = 2;

cout << countWalks(adj, src, dest, k);

return 0;

}

Java

// Java Code to count walks from src to dest // with exactly k edges using recursion class GfG {

// Function to count all walks from src to dest
// using exactly k edges
static int countWalks(int[][] adj, int src,
                      int dest, int k) {

    // Base Case: If k is 0 and src is same as dest
    if (k == 0 && src == dest) {
        return 1;
    }

    // If k is 0 and src is not dest, no walk possible
    if (k == 0) {
        return 0;
    }

    int count = 0;

    // Try all adjacent vertices from src
    for (int i = 0; i < adj.length; i++) {

        // If there is an edge from src to i
        if (adj[src][i] == 1) {

            // Recur for the remaining k-1 edges
            count += countWalks(adj, i, dest, k - 1);
        }
    }

    return count;
}

public static void main(String[] args) {

    int[][] adj = {
        {0, 1, 1, 1},
        {0, 0, 0, 1},
        {0, 0, 0, 1},
        {0, 0, 0, 0}
    };

    int src = 0, dest = 3, k = 2;

    System.out.println(countWalks(adj, src, dest, k));
}

}

Python

Python Code to count walks from src to dest

with exactly k edges using recursion

Function to count all walks from src to dest

using exactly k edges

def countWalks(adj, src, dest, k):

# Base Case: If k is 0 and src is same as dest
if k == 0 and src == dest:
    return 1

# If k is 0 and src is not dest, no walk possible
if k == 0:
    return 0

count = 0

# Try all adjacent vertices from src
for i in range(len(adj)):

    # If there is an edge from src to i
    if adj[src][i] == 1:

        # Recur for the remaining k-1 edges
        count += countWalks(adj, i, dest, k - 1)

return count

if name == "main":

adj = [
    [0, 1, 1, 1],
    [0, 0, 0, 1],
    [0, 0, 0, 1],
    [0, 0, 0, 0]
]

src = 0
dest = 3
k = 2

print(countWalks(adj, src, dest, k))

C#

// C# Code to count walks from src to dest // with exactly k edges using recursion using System;

class GfG {

// Function to count all walks from src to dest
// using exactly k edges
static int countWalks(int[,] adj, int src,
                      int dest, int k) {

    // Base Case: If k is 0 and src is same as dest
    if (k == 0 && src == dest) {
        return 1;
    }

    // If k is 0 and src is not dest, no walk possible
    if (k == 0) {
        return 0;
    }

    int count = 0;

    // Try all adjacent vertices from src
    for (int i = 0; i < adj.GetLength(0); i++) {

        // If there is an edge from src to i
        if (adj[src, i] == 1) {

            // Recur for the remaining k-1 edges
            count += countWalks(adj, i, dest, k - 1);
        }
    }

    return count;
}

static void Main() {

    int[,] adj = {
        {0, 1, 1, 1},
        {0, 0, 0, 1},
        {0, 0, 0, 1},
        {0, 0, 0, 0}
    };

    int src = 0, dest = 3, k = 2;

    Console.WriteLine(countWalks(adj, src, dest, k));
}

}

JavaScript

// JavaScript Code to count walks from src to dest // with exactly k edges using recursion

// Function to count all walks from src to dest // using exactly k edges function countWalks(adj, src, dest, k) {

// Base Case: If k is 0 and src is same as dest
if (k === 0 && src === dest) {
    return 1;
}

// If k is 0 and src is not dest, no walk possible
if (k === 0) {
    return 0;
}

let count = 0;

// Try all adjacent vertices from src
for (let i = 0; i < adj.length; i++) {

    // If there is an edge from src to i
    if (adj[src][i] === 1) {

        // Recur for the remaining k-1 edges
        count += countWalks(adj, i, dest, k - 1);
    }
}

return count;

}

// Driver Code let adj = [ [0, 1, 1, 1], [0, 0, 0, 1], [0, 0, 0, 1], [0, 0, 0, 0] ];

let src = 0, dest = 3, k = 2;

console.log(countWalks(adj, src, dest, k));

`

**[Expected Approach] Using Dynamic Programming - O(k*(v^3)) Time and O(k*(v^2)) Space

The idea is to **count walks by building the solution **bottom-up using **dynamic programming. The thought process is that if you know how many ways you can go from **one node to another in k-1 edges, you can use that to compute walks of **k edges by adding one more valid step.
We define a **3D DP table dp[e][i][j] where each entry stores the number of walks from node i to node j using **exactly e edges.
The observation is that a walk of length k from i to j can be formed by going from i to any neighbor a, and then completing the remaining **k-1 steps from a to j.

Steps to implement the above idea:

// C++ Code to count walks from src to dest // with exactly k edges using DP #include #include using namespace std;

// Function to count all walks from src to dest // using exactly k edges with bottom-up DP int countWalks(vector<vector> &adj, int src, int dest, int k) {

int v = adj.size();

// dp[e][i][j]: number of walks from i to j using e edges
vector<vector<vector<int>>> dp(
    k + 1, vector<vector<int>>(v, vector<int>(v, 0)));

// Base case: walks from i to j with 0 edges
for (int i = 0; i < v; i++) {
    dp[0][i][i] = 1;
}

// Build the table for all edge counts from 1 to k
for (int e = 1; e <= k; e++) {
    for (int i = 0; i < v; i++) {
        for (int j = 0; j < v; j++) {

            // Consider all intermediate vertices
            for (int a = 0; a < v; a++) {

                // If there's an edge from i to a
                if (adj[i][a] == 1) {
                    dp[e][i][j] += dp[e - 1][a][j];
                }
            }
        }
    }
}

return dp[k][src][dest];

}

int main() {

vector<vector<int>> adj = {
    {0, 1, 1, 1},
    {0, 0, 0, 1},
    {0, 0, 0, 1},
    {0, 0, 0, 0}
};

int src = 0, dest = 3, k = 2;

cout << countWalks(adj, src, dest, k);

return 0;

}

Java

// Java Code to count walks from src to dest // with exactly k edges using DP class GfG {

// Function to count all walks from src to dest
// using exactly k edges with bottom-up DP
static int countWalks(int[][] adj, int src, int dest, int k) {

    int v = adj.length;

    // dp[e][i][j]: number of walks from i to j using e edges
    int[][][] dp = new int[k + 1][v][v];

    // Base case: walks from i to j with 0 edges
    for (int i = 0; i < v; i++) {
        dp[0][i][i] = 1;
    }

    // Build the table for all edge counts from 1 to k
    for (int e = 1; e <= k; e++) {
        for (int i = 0; i < v; i++) {
            for (int j = 0; j < v; j++) {

                // Consider all intermediate vertices
                for (int a = 0; a < v; a++) {

                    // If there's an edge from i to a
                    if (adj[i][a] == 1) {
                        dp[e][i][j] += dp[e - 1][a][j];
                    }
                }
            }
        }
    }

    return dp[k][src][dest];
}

public static void main(String[] args) {

    int[][] adj = {
        {0, 1, 1, 1},
        {0, 0, 0, 1},
        {0, 0, 0, 1},
        {0, 0, 0, 0}
    };

    int src = 0, dest = 3, k = 2;

    System.out.println(countWalks(adj, src, dest, k));
}

}

Python

Python Code to count walks from src to dest

with exactly k edges using DP

Function to count all walks from src to dest

using exactly k edges with bottom-up DP

def countWalks(adj, src, dest, k):

v = len(adj)

# dp[e][i][j]: number of walks from i to j using e edges
dp = [[[0 for _ in range(v)] for _ in range(v)] for _ in range(k + 1)]

# Base case: walks from i to j with 0 edges
for i in range(v):
    dp[0][i][i] = 1

# Build the table for all edge counts from 1 to k
for e in range(1, k + 1):
    for i in range(v):
        for j in range(v):

            # Consider all intermediate vertices
            for a in range(v):

                # If there's an edge from i to a
                if adj[i][a] == 1:
                    dp[e][i][j] += dp[e - 1][a][j]

return dp[k][src][dest]

if name == "main":

adj = [
    [0, 1, 1, 1],
    [0, 0, 0, 1],
    [0, 0, 0, 1],
    [0, 0, 0, 0]
]

src, dest, k = 0, 3, 2

print(countWalks(adj, src, dest, k))

C#

// C# Code to count walks from src to dest // with exactly k edges using DP using System;

class GfG {

// Function to count all walks from src to dest
// using exactly k edges with bottom-up DP
public static int countWalks(int[][] adj,
                             int src, int dest, int k) {

    int v = adj.Length;

    // dp[e][i][j]: number of walks from i to j using e edges
    int[,,] dp = new int[k + 1, v, v];

    // Base case: walks from i to j with 0 edges
    for (int i = 0; i < v; i++) {
        dp[0, i, i] = 1;
    }

    // Build the table for all edge counts from 1 to k
    for (int e = 1; e <= k; e++) {
        for (int i = 0; i < v; i++) {
            for (int j = 0; j < v; j++) {

                // Consider all intermediate vertices
                for (int a = 0; a < v; a++) {

                    // If there's an edge from i to a
                    if (adj[i][a] == 1) {
                        dp[e, i, j] += dp[e - 1, a, j];
                    }
                }
            }
        }
    }

    return dp[k, src, dest];
}

static void Main() {

    int[][] adj = new int[][] {
        new int[] {0, 1, 1, 1},
        new int[] {0, 0, 0, 1},
        new int[] {0, 0, 0, 1},
        new int[] {0, 0, 0, 0}
    };

    int src = 0, dest = 3, k = 2;

    Console.WriteLine(countWalks(adj, src, dest, k));
}

}

JavaScript

// JavaScript Code to count walks from src to dest // with exactly k edges using DP

// Function to count all walks from src to dest // using exactly k edges with bottom-up DP function countWalks(adj, src, dest, k) {

const v = adj.length;

// dp[e][i][j]: number of walks from i to j using e edges
const dp = Array.from({ length: k + 1 }, () =>
    Array.from({ length: v }, () => Array(v).fill(0))
);

// Base case: walks from i to j with 0 edges
for (let i = 0; i < v; i++) {
    dp[0][i][i] = 1;
}

// Build the table for all edge counts from 1 to k
for (let e = 1; e <= k; e++) {
    for (let i = 0; i < v; i++) {
        for (let j = 0; j < v; j++) {

            // Consider all intermediate vertices
            for (let a = 0; a < v; a++) {

                // If there's an edge from i to a
                if (adj[i][a] === 1) {
                    dp[e][i][j] += dp[e - 1][a][j];
                }
            }
        }
    }
}

return dp[k][src][dest];

}

// Driver Code const adj = [ [0, 1, 1, 1], [0, 0, 0, 1], [0, 0, 0, 1], [0, 0, 0, 0] ];

const src = 0, dest = 3, k = 2;

console.log(countWalks(adj, src, dest, k));

`