计算从一个源到一个目的地的所有可能的步行,精确到k边

给定一个有向图和其中的两个顶点“u”和“v”,计算从“u”到“v”的所有可能的走行,走行上正好有k条边。 给出了图表 邻接矩阵表示法 其中,图[i][j]的值为1表示从顶点i到顶点j有一条边,值为0表示从i到j没有边。

null

例如,考虑下面的图表。让源“u”为顶点0,目标“v”为3,k为2。输出应该是2,因为从0到3有两次行走,正好有两条边。步行是{0,2,3}和{0,1,3}

graph

简单方法 :创建一个递归函数,用于获取当前顶点、目标顶点和顶点计数。使用当前顶点的所有相邻顶点调用递归函数,该顶点的k值为k-1。当k的值为0时,检查当前顶点是否为目标。如果是destination,则输出答案为1。

下面是这个简单解决方案的实现。

C++

// C++ program to count walks from u to
// v with exactly k edges
#include <iostream>
using namespace std;
// Number of vertices in the graph
#define V 4
// A naive recursive function to count
// walks from u to v with k edges
int countwalks( int graph[][V], int u, int v, int k)
{
// Base cases
if (k == 0 && u == v)
return 1;
if (k == 1 && graph[u][v])
return 1;
if (k <= 0)
return 0;
// Initialize result
int count = 0;
// Go to all adjacents of u and recur
for ( int i = 0; i < V; i++)
if (graph[u][i] == 1) // Check if is adjacent of u
count += countwalks(graph, i, v, k - 1);
return count;
}
// driver program to test above function
int main()
{
/* Let us create the graph shown in above diagram*/
int graph[V][V] = { { 0, 1, 1, 1 },
{ 0, 0, 0, 1 },
{ 0, 0, 0, 1 },
{ 0, 0, 0, 0 } };
int u = 0, v = 3, k = 2;
cout << countwalks(graph, u, v, k);
return 0;
}


JAVA

// Java program to count walks from u to v with exactly k edges
import java.util.*;
import java.lang.*;
import java.io.*;
class KPaths {
static final int V = 4 ; // Number of vertices
// A naive recursive function to count walks from u
// to v with k edges
int countwalks( int graph[][], int u, int v, int k)
{
// Base cases
if (k == 0 && u == v)
return 1 ;
if (k == 1 && graph[u][v] == 1 )
return 1 ;
if (k <= 0 )
return 0 ;
// Initialize result
int count = 0 ;
// Go to all adjacents of u and recur
for ( int i = 0 ; i < V; i++)
if (graph[u][i] == 1 ) // Check if is adjacent of u
count += countwalks(graph, i, v, k - 1 );
return count;
}
// Driver method
public static void main(String[] args) throws java.lang.Exception
{
/* Let us create the graph shown in above diagram*/
int graph[][] = new int [][] { { 0 , 1 , 1 , 1 },
{ 0 , 0 , 0 , 1 },
{ 0 , 0 , 0 , 1 },
{ 0 , 0 , 0 , 0 } };
int u = 0 , v = 3 , k = 2 ;
KPaths p = new KPaths();
System.out.println(p.countwalks(graph, u, v, k));
}
} // Contributed by Aakash Hasija


Python3

# Python3 program to count walks from
# u to v with exactly k edges
# Number of vertices in the graph
V = 4
# A naive recursive function to count
# walks from u to v with k edges
def countwalks(graph, u, v, k):
# Base cases
if (k = = 0 and u = = v):
return 1
if (k = = 1 and graph[u][v]):
return 1
if (k < = 0 ):
return 0
# Initialize result
count = 0
# Go to all adjacents of u and recur
for i in range ( 0 , V):
# Check if is adjacent of u
if (graph[u][i] = = 1 ):
count + = countwalks(graph, i, v, k - 1 )
return count
# Driver Code
# Let us create the graph shown in above diagram
graph = [[ 0 , 1 , 1 , 1 , ],
[ 0 , 0 , 0 , 1 , ],
[ 0 , 0 , 0 , 1 , ],
[ 0 , 0 , 0 , 0 ] ]
u = 0 ; v = 3 ; k = 2
print (countwalks(graph, u, v, k))
# This code is contributed by Smitha Dinesh Semwal.


C#

// C# program to count walks from u to
// v with exactly k edges
using System;
class GFG {
// Number of vertices
static int V = 4;
// A naive recursive function to
// count walks from u to v with
// k edges
static int countwalks( int [, ] graph, int u,
int v, int k)
{
// Base cases
if (k == 0 && u == v)
return 1;
if (k == 1 && graph[u, v] == 1)
return 1;
if (k <= 0)
return 0;
// Initialize result
int count = 0;
// Go to all adjacents of u and recur
for ( int i = 0; i < V; i++)
// Check if is adjacent of u
if (graph[u, i] == 1)
count += countwalks(graph, i, v, k - 1);
return count;
}
// Driver method
public static void Main()
{
/* Let us create the graph shown
in above diagram*/
int [, ] graph = new int [, ] { { 0, 1, 1, 1 },
{ 0, 0, 0, 1 },
{ 0, 0, 0, 1 },
{ 0, 0, 0, 0 } };
int u = 0, v = 3, k = 2;
Console.Write(
countwalks(graph, u, v, k));
}
}
// This code is contributed by nitin mittal.


PHP

<?php
// PHP program to count walks from u
// to v with exactly k edges
// Number of vertices in the graph
$V = 4;
// A naive recursive function to count
// walks from u to v with k edges
function countwalks( $graph , $u , $v , $k )
{
global $V ;
// Base cases
if ( $k == 0 and $u == $v )
return 1;
if ( $k == 1 and $graph [ $u ][ $v ])
return 1;
if ( $k <= 0)
return 0;
// Initialize result
$count = 0;
// Go to all adjacents of u and recur
for ( $i = 0; $i < $V ; $i ++)
// Check if is adjacent of u
if ( $graph [ $u ][ $i ] == 1)
$count += countwalks( $graph , $i ,
$v , $k - 1);
return $count ;
}
// Driver Code
/* Let us create the graph
shown in above diagram*/
$graph = array ( array (0, 1, 1, 1),
array (0, 0, 0, 1),
array (0, 0, 0, 1),
array (0, 0, 0, 0));
$u = 0; $v = 3; $k = 2;
echo countwalks( $graph , $u , $v , $k );
// This code is contributed by anuj_67.
?>


Javascript

<script>
// Javascript program to count walks from u to
// v with exactly k edges
// Number of vertices in the graph
var V = 4
// A naive recursive function to count
// walks from u to v with k edges
function countwalks(graph, u, v, k)
{
// Base cases
if (k == 0 && u == v)
return 1;
if (k == 1 && graph[u][v])
return 1;
if (k <= 0)
return 0;
// Initialize result
var count = 0;
// Go to all adjacents of u and recur
for ( var i = 0; i < V; i++)
if (graph[u][i] == 1) // Check if is adjacent of u
count += countwalks(graph, i, v, k - 1);
return count;
}
// driver program to test above function
/* Let us create the graph shown in above diagram*/
var graph = [[0, 1, 1, 1, ],
[0, 0, 0, 1, ],
[0, 0, 0, 1, ],
[0, 0, 0, 0] ];
var u = 0, v = 3, k = 2;
document.write(countwalks(graph, u, v, k));
// This code contributed by shubhamsingh10
</script>


输出:

2

复杂性分析:

  • 时间复杂性: O(V) K ). 上述函数的最坏情况时间复杂度为O(V K )其中V是给定图形中的顶点数。我们可以简单地通过绘制递归树来分析时间复杂度。最坏的情况发生在完整的图形中。在最坏的情况下,递归树的每个内部节点正好有n个子节点。
  • 辅助空间: O(V)。 要存储堆栈空间和访问的阵列,需要O(V)空间。

有效方法: 可以使用 动态规划 其想法是建立一个3D表格,其中第一个维度是源,第二个维度是目标,第三个维度是从源到目标的边数,值是行走次数。和其他人一样, 动态规划问题 ,以自下而上的方式填充3D表格。

C++

// C++ program to count walks from
// u to v with exactly k edges
#include <iostream>
using namespace std;
// Number of vertices in the graph
#define V 4
// A Dynamic programming based function to count walks from u
// to v with k edges
int countwalks( int graph[][V], int u, int v, int k)
{
// Table to be filled up using DP.
// The value count[i][j][e] will
// store count of possible walks from
// i to j with exactly k edges
int count[V][V][k + 1];
// Loop for number of edges from 0 to k
for ( int e = 0; e <= k; e++) {
for ( int i = 0; i < V; i++) // for source
{
for ( int j = 0; j < V; j++) // for destination
{
// initialize value
count[i][j][e] = 0;
// from base cases
if (e == 0 && i == j)
count[i][j][e] = 1;
if (e == 1 && graph[i][j])
count[i][j][e] = 1;
// go to adjacent only when the
// number of edges is more than 1
if (e > 1) {
for ( int a = 0; a < V; a++) // adjacent of source i
if (graph[i][a])
count[i][j][e] += count[a][j][e - 1];
}
}
}
}
return count[u][v][k];
}
// driver program to test above function
int main()
{
/* Let us create the graph shown in above diagram*/
int graph[V][V] = { { 0, 1, 1, 1 },
{ 0, 0, 0, 1 },
{ 0, 0, 0, 1 },
{ 0, 0, 0, 0 } };
int u = 0, v = 3, k = 2;
cout << countwalks(graph, u, v, k);
return 0;
}


JAVA

// Java program to count walks from
// u to v with exactly k edges
import java.util.*;
import java.lang.*;
import java.io.*;
class KPaths {
static final int V = 4 ; // Number of vertices
// A Dynamic programming based function to count walks from u
// to v with k edges
int countwalks( int graph[][], int u, int v, int k)
{
// Table to be filled up using DP. The value count[i][j][e]
// will/ store count of possible walks from i to j with
// exactly k edges
int count[][][] = new int [V][V][k + 1 ];
// Loop for number of edges from 0 to k
for ( int e = 0 ; e <= k; e++) {
for ( int i = 0 ; i < V; i++) // for source
{
for ( int j = 0 ; j < V; j++) // for destination
{
// initialize value
count[i][j][e] = 0 ;
// from base cases
if (e == 0 && i == j)
count[i][j][e] = 1 ;
if (e == 1 && graph[i][j] != 0 )
count[i][j][e] = 1 ;
// go to adjacent only when number of edges
// is more than 1
if (e > 1 ) {
for ( int a = 0 ; a < V; a++) // adjacent of i
if (graph[i][a] != 0 )
count[i][j][e] += count[a][j][e - 1 ];
}
}
}
}
return count[u][v][k];
}
// Driver method
public static void main(String[] args) throws java.lang.Exception
{
/* Let us create the graph shown in above diagram*/
int graph[][] = new int [][] { { 0 , 1 , 1 , 1 },
{ 0 , 0 , 0 , 1 },
{ 0 , 0 , 0 , 1 },
{ 0 , 0 , 0 , 0 } };
int u = 0 , v = 3 , k = 2 ;
KPaths p = new KPaths();
System.out.println(p.countwalks(graph, u, v, k));
}
} // Contributed by Aakash Hasija


Python3

# Python3 program to count walks from
# u to v with exactly k edges
# Number of vertices
V = 4
# A Dynamic programming based function
# to count walks from u to v with k edges
def countwalks(graph, u, v, k):
# Table to be filled up using DP.
# The value count[i][j][e] will/
# store count of possible walks
# from i to j with exactly k edges
count = [[[ 0 for k in range (k + 1 )]
for i in range (V)]
for j in range (V)]
# Loop for number of edges from 0 to k
for e in range ( 0 , k + 1 ):
# For Source
for i in range (V):
# For Destination
for j in range (V):
# Initialize value
# count[i][j][e] = 0
# From base cases
if (e = = 0 and i = = j):
count[i][j][e] = 1
if (e = = 1 and graph[i][j] ! = 0 ):
count[i][j][e] = 1
# Go to adjacent only when number
# of edges is more than 1
if (e > 1 ):
for a in range (V):
# Adjacent of i
if (graph[i][a] ! = 0 ):
count[i][j][e] + = count[a][j][e - 1 ]
return count[u][v][k]
# Driver code
if __name__ = = '__main__' :
# Let us create the graph shown
# in above diagram
graph = [[ 0 , 1 , 1 , 1 ],
[ 0 , 0 , 0 , 1 ],
[ 0 , 0 , 0 , 1 ],
[ 0 , 0 , 0 , 0 ]]
u = 0
v = 3
k = 2
print (countwalks(graph, u, v, k))
# This code is contributed by Rajput-Ji


C#

// C# program to count walks from u to v
// with exactly k edges
using System;
class GFG {
static int V = 4; // Number of vertices
// A Dynamic programming based function
// to count walks from u to v with k edges
static int countwalks( int [, ] graph, int u,
int v, int k)
{
// Table to be filled up using DP. The
// value count[i][j][e] will/ store
// count of possible walks from i to
// j with exactly k edges
int [,, ] count = new int [V, V, k + 1];
// Loop for number of edges from 0 to k
for ( int e = 0; e <= k; e++) {
// for source
for ( int i = 0; i < V; i++) {
// for destination
for ( int j = 0; j < V; j++) {
// initialize value
count[i, j, e] = 0;
// from base cases
if (e == 0 && i == j)
count[i, j, e] = 1;
if (e == 1 && graph[i, j] != 0)
count[i, j, e] = 1;
// go to adjacent only when
// number of edges
// is more than 1
if (e > 1) {
// adjacent of i
for ( int a = 0; a < V; a++)
if (graph[i, a] != 0)
count[i, j, e] += count[a, j, e - 1];
}
}
}
}
return count[u, v, k];
}
// Driver method
public static void Main()
{
/* Let us create the graph shown in
above diagram*/
int [, ] graph = { { 0, 1, 1, 1 },
{ 0, 0, 0, 1 },
{ 0, 0, 0, 1 },
{ 0, 0, 0, 0 } };
int u = 0, v = 3, k = 2;
Console.WriteLine(
countwalks(graph, u, v, k));
}
}
// This is Code Contributed by anuj_67.


Javascript

<script>
// Javascript program to count walks from
// u to v with exactly k edges
// Number of vertices in the graph
var V = 4
// A Dynamic programming based function to count walks from u
// to v with k edges
function countwalks(graph, u, v, k)
{
// Table to be filled up using DP.
// The value count[i][j][e] will
// store count of possible walks from
// i to j with exactly k edges
var count = new Array(V);
for ( var i = 0; i <V; i++) {
count[i] = new Array(V);
for ( var j = 0; j < V; j++) {
count[i][j] = new Array(V);
for ( var e = 0; e <= k; e++) {
count[i][j][e] = 0;
}
}
}
// Loop for number of edges from 0 to k
for ( var e = 0; e <= k; e++) {
for ( var i = 0; i < V; i++) // for source
{
for ( var j = 0; j < V; j++) // for destination
{
// initialize value
count[i][j][e] = 0;
// from base cases
if (e == 0 && i == j)
count[i][j][e] = 1;
if (e == 1 && graph[i][j])
count[i][j][e] = 1;
// go to adjacent only when the
// number of edges is more than 1
if (e > 1) {
for ( var a = 0; a < V; a++) // adjacent of source i
if (graph[i][a])
count[i][j][e] += count[a][j][e - 1];
}
}
}
}
return count[u][v][k];
}
// driver program to test above function
/* Let us create the graph shown in above diagram*/
var graph = [ [ 0, 1, 1, 1 ],
[ 0, 0, 0, 1 ],
[ 0, 0, 0, 1 ],
[ 0, 0, 0, 0 ] ];
var u = 0, v = 3, k = 2;
document.write(countwalks(graph, u, v, k));
// This code is contributed by ShubhamSingh10
</script>


输出:

2

复杂性分析:

  • 时间复杂性: O(V) 3. ). 填充DP表需要三个嵌套循环,因此时间复杂度为O(V) 3/sup>)。
  • 辅助空间: O(V) 3. ). 存储DP表O(V 3. )需要空间。

我们也可以使用 分而治之 在O(V)中解决上述问题 3. 时间到了。从u到v长度为k的行走计数是(图[v][v]中的第[u][v]项) K .我们可以通过使用 计算功率的分治技术 .两个大小为V x V的矩阵之间的乘法取O(V 3. )时间到了。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享