Skip to content
Related Articles

Related Articles

Improve Article

All vertex pairs connected with exactly k edges in a graph

  • Difficulty Level : Medium
  • Last Updated : 18 Jun, 2021

Given a directed graph represented as an adjacency matrix and an integer ‘k’, the task is to find all the vertex pairs that are connected with exactly ‘k’ edges. 
Also, find the number of ways in which the two vertices can be linked in exactly k edges.

Examples :  

Input : k = 3 and graph :
0 1 0 0 0 
0 0 1 0 0 
0 0 0 1 1 
1 0 0 0 0 
0 0 1 0 0 
Output :
1 -> 4 in 1 way(s)
1 -> 5 in 1 way(s)
2 -> 1 in 1 way(s)
2 -> 3 in 1 way(s)
3 -> 2 in 1 way(s)
3 -> 4 in 1 way(s)
3 -> 5 in 1 way(s)
4 -> 3 in 1 way(s)
5 -> 1 in 1 way(s)
5 -> 3 in 1 way(s)

Input : k = 2 and graph :
0 0 0 
1 0 1 
0 1 0 
Output :
2 -> 2 in 1 way(s)
3 -> 1 in 1 way(s)
3 -> 3 in 1 way(s)

Approach :  

  • We will multiply the adjacency matrix with itself ‘k’ number of times.
  • In the resultant matrix, res[i][j] will be the number of ways in which vertex ‘j’ can be reached from vertex ‘i’ covering exactly ‘k’ edges.

Below is the implementation of the above approach :  

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to multiply two square matrices
vector<vector<int>> multiplyMatrices(
  vector<vector<int>> arr1,
  vector<vector<int>> arr2)
{
  int order = arr1.size();
  vector<vector<int>> ans(order, vector<int>(order));
   
  for(int i = 0; i < order; i++)
  {
    for(int j = 0; j < order; j++)
    {
      for(int k = 0; k < order; k++)
      {
        ans[i][j] += arr1[i][k] * arr2[k][j];
      }
    }
  }
  return ans;
}
 
// Function to find all the pairs that
// can be connected with exactly 'k' edges
void solve(vector<vector<int>> arr, int k)
{
  vector<vector<int>> res(
    arr.size(), vector<int>(arr[0].size()));
   
  // Copying arr to res,
  // which is the result for k=1
  for(int i = 0; i < res.size(); i++)
    for(int j = 0; j < res.size(); j++)
      res[i][j] = arr[i][j];
 
  // Multiplying arr with itself
  // the required number of times
  for(int i = 2; i <= k; i++)
    res = multiplyMatrices(res, arr);
 
  for(int i = 0; i < res.size(); i++)
    for(int j = 0; j < res.size(); j++)
       
      // If there is a path between 'i'
      // and 'j' in exactly 'k' edges
      if (res[i][j] > 0)
      {
        cout << i << " -> " << j
             << " in " << res[i][j]
             << " way(s)" << endl;
      }
}
 
// Driver code
int main(int argc, char const *argv[])
{
  vector<vector<int>> arr(5, vector<int>(5));
  arr[0][1] = 1;
  arr[1][2] = 1;
  arr[2][3] = 1;
  arr[2][4] = 1;
  arr[3][0] = 1;
  arr[4][2] = 1;
  int k = 3;
   
  solve(arr, k);
}
 
// This code is contributed by sanjeev2552

Java




// Java implementation of the approach
public class KPaths {
 
    // Function to multiply two square matrices
    static int[][] multiplyMatrices(int[][] arr1, int[][] arr2)
    {
        int order = arr1.length;
        int[][] ans = new int[order][order];
        for (int i = 0; i < order; i++) {
            for (int j = 0; j < order; j++) {
                for (int k = 0; k < order; k++) {
                    ans[i][j] += arr1[i][k] * arr2[k][j];
                }
            }
        }
        return ans;
    }
 
    // Function to find all the pairs that
    // can be connected with exactly 'k' edges
    static void solve(int[][] arr, int k)
    {
        int[][] res = new int[arr.length][arr[0].length];
 
        // copying arr to res,
        // which is the result for k=1
        for (int i = 0; i < res.length; i++)
            for (int j = 0; j < res.length; j++)
                res[i][j] = arr[i][j];
 
        // multiplying arr with itself
        // the required number of times
        for (int i = 2; i <= k; i++)
            res = multiplyMatrices(res, arr);
 
        for (int i = 0; i < res.length; i++)
            for (int j = 0; j < res.length; j++)
 
                // if there is a path between 'i'
                // and 'j' in exactly 'k' edges
                if (res[i][j] > 0)
                    System.out.println(i + " -> " + j + " in " + res[i][j] + " way(s)");
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int[][] arr = new int[5][5];
        arr[0][1] = 1;
        arr[1][2] = 1;
        arr[2][3] = 1;
        arr[2][4] = 1;
        arr[3][0] = 1;
        arr[4][2] = 1;
        int k = 3;
        solve(arr, k);
    }
}

Python3




# Python3 implementation of the approach
 
# Function to multiply two square matrices
def multiplyMatrices(arr1, arr2):
 
    order = len(arr1)
    ans = [[0 for i in range(order)] for j in range(order)]
 
    for i in range(order):
        for j in range(order):
            for k in range(order):
                ans[i][j] += arr1[i][k] * arr2[k][j]
 
    return ans
 
 
# Function to find all the pairs that
# can be connected with exactly 'k' edges
def solve(arr, k):
    res = [[0 for i in range(len(arr))] for j in range(len(arr))]
 
    # Copying arr to res,
    # which is the result for k=1
    for i in range(len(arr)):
        for j in range(len(arr)):
            res[i][j] = arr[i][j]
 
    # Multiplying arr with itself
    # the required number of times
    for i in range(2, k+1):
        res = multiplyMatrices(res, arr)
 
    for i in range(len(arr)):
        for j in range(len(arr)):
 
            # If there is a path between 'i'
            # and 'j' in exactly 'k' edges
            if (res[i][j] > 0):
                print(i, "->", j, "in", res[i][j], "way(s)")
 
 
# Driver Code
if __name__ == "__main__":
 
    arr = [1, 2, 3, 4]
    arr = [[0 for i in range(5)] for j in range(5)]
    arr[0][1] = 1
    arr[1][2] = 1
    arr[2][3] = 1
    arr[2][4] = 1
    arr[3][0] = 1
    arr[4][2] = 1
    k = 3
 
    solve(arr, k)
     
# This code is contributed by kirtishsurangalikar

C#




// C# implementation of the approach
using System;
 
class KPaths
{
 
// Function to multiply two square matrices
static int[,] multiplyMatrices(int[,] arr1,
                               int[,] arr2)
{
    int order = arr1.GetLength(0);
    int[,] ans = new int[order, order];
    for (int i = 0; i < order; i++)
    {
        for (int j = 0; j < order; j++)
        {
            for (int k = 0; k < order; k++)
            {
                ans[i, j] += arr1[i, k] *
                             arr2[k, j];
            }
        }
    }
    return ans;
}
 
// Function to find all the pairs that
// can be connected with exactly 'k' edges
static void solve(int[,] arr, int k)
{
    int[,] res = new int[arr.GetLength(0),
                         arr.GetLength(1)];
 
    // copying arr to res,
    // which is the result for k = 1
    for (int i = 0; i < res.GetLength(0); i++)
        for (int j = 0; j < res.GetLength(1); j++)
            res[i, j] = arr[i, j];
 
    // multiplying arr with itself
    // the required number of times
    for (int i = 2; i <= k; i++)
        res = multiplyMatrices(res, arr);
 
    for (int i = 0; i < res.GetLength(0); i++)
        for (int j = 0; j < res.GetLength(1); j++)
 
            // if there is a path between 'i'
            // and 'j' in exactly 'k' edges
            if (res[i,j] > 0)
                Console.WriteLine(i + " -> " + j + " in " +
                                    res[i, j] + " way(s)");
}
 
// Driver code
public static void Main(String[] args)
{
    int[,] arr = new int[5, 5];
    arr[0, 1] = 1;
    arr[1, 2] = 1;
    arr[2, 3] = 1;
    arr[2, 4] = 1;
    arr[3, 0] = 1;
    arr[4, 2] = 1;
    int k = 3;
    solve(arr, k);
}
}
 
// This code is contributed by Rajput-Ji
Output



0 -> 3 in 1 way(s)
0 -> 4 in 1 way(s)
1 -> 0 in 1 way(s)
1 -> 2 in 1 way(s)
2 -> 1 in 1 way(s)
2 -> 3 in 1 way(s)
2 -> 4 in 1 way(s)
3 -> 2 in 1 way(s)
4 -> 0 in 1 way(s)
4 -> 2 in 1 way(s)

The time complexity of the above code can be reduced for large values of k by using matrix exponentitation. The complexity can be changed from O(n^3 * k) to O(n^3 * log k) 

Java




class KPaths {
 
    // Function to multiply two square matrices
    static int[][] multiplyMatrices(int[][] arr1, int[][] arr2)
    {
        int order = arr1.length;
        int[][] ans = new int[order][order];
        for (int i = 0; i < order; i++) {
            for (int j = 0; j < order; j++) {
                for (int k = 0; k < order; k++) {
                    ans[i][j] += arr1[i][k] * arr2[k][j];
                }
            }
        }
        return ans;
    }
 
    // Function to find all the pairs that
    // can be connected with exactly 'k' edges
    static void solve(int[][] arr, int k)
    {
        int[][] res = new int[arr.length][arr[0].length];
 
        res = power(arr, k, arr[0].length);
        for (int i = 0; i < res.length; i++)
            for (int j = 0; j < res.length; j++)
 
                // if there is a path between 'i'
                // and 'j' in exactly 'k' edges
                if (res[i][j] > 0)
                    System.out.println(i + " -> " + j + " in " + res[i][j] + " way(s)");
    }
 
    static int[][] power(int x[][], int y, int n)
    {
        // MATRIX EXPONENTIATION
        // Initialize result
        int res[][] = identity(n);
 
        while (y > 0) {
 
            if ((y & 1) == 1)
                res = multiplyMatrices(res, x);
 
            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = multiplyMatrices(x, x);
        }
        return res;
    }
    static int[][] identity(int n)
    {
        // returns identity matrix of order n
        int r[][] = new int[n][n];
        for (int i = 0; i < n; i++)
            r[i][i] = 1;
 
        return r;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int[][] arr = new int[5][5];
        arr[0][1] = 1;
        arr[1][2] = 1;
        arr[2][3] = 1;
        arr[2][4] = 1;
        arr[3][0] = 1;
        arr[4][2] = 1;
        int k = 3;
        solve(arr, k);
    }
}

C#




// C# implementation of the above approach:
using System;
 
class KPaths
{
 
    // Function to multiply two square matrices
    static int[,] multiplyMatrices(int[,] arr1,
                                   int[,] arr2)
    {
        int order = arr1.GetLength(0);
        int[,] ans = new int[order,order];
        for (int i = 0; i < order; i++)
        {
            for (int j = 0; j < order; j++)
            {
                for (int k = 0; k < order; k++)
                {
                    ans[i, j] += arr1[i, k] *
                                 arr2[k, j];
                }
            }
        }
        return ans;
    }
 
    // Function to find all the pairs that
    // can be connected with exactly 'k' edges
    static void solve(int[,] arr, int k)
    {
        int[,] res = new int[arr.GetLength(0),
                             arr.GetLength(1)];
 
        res = power(arr, k, arr.GetLength(0));
        for (int i = 0; i < res.GetLength(0); i++)
            for (int j = 0; j < res.GetLength(1); j++)
 
                // if there is a path between 'i'
                // and 'j' in exactly 'k' edges
                if (res[i, j] > 0)
                    Console.WriteLine(i + " -> " + j + 
                      " in " + res[i, j] + " way(s)");
    }
 
    static int[,] power(int [,]x, int y, int n)
    {
         
        // MATRIX EXPONENTIATION
        // Initialize result
        int [,]res = identity(n);
 
        while (y > 0)
        {
 
            if ((y & 1) == 1)
                res = multiplyMatrices(res, x);
 
            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = multiplyMatrices(x, x);
        }
        return res;
    }
     
    static int[,] identity(int n)
    {
        // returns identity matrix of order n
        int [,]r = new int[n, n];
        for (int i = 0; i < n; i++)
            r[i, i] = 1;
 
        return r;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int[,] arr = new int[5, 5];
        arr[0, 1] = 1;
        arr[1, 2] = 1;
        arr[2, 3] = 1;
        arr[2, 4] = 1;
        arr[3, 0] = 1;
        arr[4, 2] = 1;
        int k = 3;
        solve(arr, k);
    }
}
 
// This code is contributed by PrinciRaj1992

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :