Open In App

Count all possible walks from a source to a destination with exactly k edges

Last Updated : 12 Jun, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

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).

[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 <iostream>
#include <vector>
using namespace std;

// Function to count all walks from src to dest
// using exactly k edges
int countWalks(vector<vector<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.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));

Output
2

[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:

  • Create a 3D DP table dp where dp[e][i][j] stores walks from i to j using e edges.
  • Initialize dp[0][i][i] = 1 for all nodes i since 0-length walk from a node to itself is 1.
  • Iterate e from 1 to k to build solutions incrementally for each edge count up to k.
  • For each edge count e, iterate over all pairs (i, j) representing source and destination nodes.
  • For each (i, j) pair, loop over all intermediate nodes a that are direct neighbors of i.
  • If there's an edge from i to a, add dp[e-1][a][j] to dp[e][i][j] to extend the walk.
  • Finally, return dp[k][src][dest] which stores walks from src to dest using exactly k edges.
C++
// C++ Code to count walks from src to dest
// with exactly k edges using DP
#include <iostream>
#include <vector>
using namespace std;

// Function to count all walks from src to dest
// using exactly k edges with bottom-up DP
int countWalks(vector<vector<int>> &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));

Output
2



Similar Reads