📌  相关文章
📜  图中所有与恰好 k 条边相连的顶点对

📅  最后修改于: 2022-05-13 01:57:54.546000             🧑  作者: Mango

图中所有与恰好 k 条边相连的顶点对

给定一个表示为邻接矩阵和整数“k”的有向图,任务是找到与恰好“k”条边相连的所有顶点对。
此外,找出两个顶点可以在恰好 k 个边中链接的方式的数量。

例子 :

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)

方法 :

  • 我们将邻接矩阵乘以自身“k”次。
  • 在结果矩阵中, res[i][j] 将是从恰好覆盖“k”条边的顶点“i”到达顶点“j”的方式数。

以下是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function to multiply two square matrices
vector> multiplyMatrices(
  vector> arr1,
  vector> arr2)
{
  int order = arr1.size();
  vector> ans(order, vector(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> arr, int k)
{
  vector> res(
    arr.size(), vector(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> arr(5, vector(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


Javascript


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


输出
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)

对于较大的 k 值,可以通过使用矩阵求幂来降低上述代码的时间复杂度。复杂度可以从O(n^3 * k)变为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