图中所有与恰好 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