未加权和有向图中的最短路径数
给定一个未加权的有向图,可以是循环的或非循环的。打印从给定顶点到每个顶点的最短路径数。例如,考虑下图。顶点 0 到顶点 0 有一条最短路径(从每个顶点到自身都有一条最短路径),顶点 0 到顶点 2 之间有一条最短路径(0->2),从顶点 0 有 4 条不同的最短路径到顶点 6:
1. 0->1->3->4->6
2. 0->1->3->5->6
3. 0->2->3->4->6
4. 0->2->3->5->6
这个想法是使用 BFS。我们使用两个数组,分别称为 dist[] 和 paths[],dist[] 表示到源顶点的最短距离,paths[] 表示从源顶点到每个顶点的不同最短路径的数量。最初 dist[] 中的所有元素都是无穷大,除了源顶点等于 0,因为到源顶点到自身的距离是 0,并且 paths[] 中的所有元素除了源顶点等于 1 之外都是 0,因为每个顶点都有一条到自己的最短路径。之后,我们开始使用 BFS 方式遍历图。
然后,对于每个顶点 X 的每个邻居 Y,执行:
1) 如果 dist[Y] > dist[X]+1 将 dist[Y] 减少到 dist[X] +1 并将顶点 X 的路径数分配给顶点 Y 的路径数。
2) else if dist[Y] = dist[X] + 1,则将顶点 X 的路径数与顶点 Y 的路径数相加。
例如:
让我们看一下下面的图表。源顶点为 0。假设我们遍历顶点 2,我们检查它的所有邻居,只有 3。因为当我们遍历顶点 1 时已经访问了顶点 3,dist[3] = 2 和 paths[3] = 1 .第二个条件为真,所以说明已经找到了额外的最短路径,所以我们把顶点3的路径数加上顶点2的路径数。
当我们遍历顶点 5 时,会发生相等的情况:
C++
// CPP program to count number of shortest
// paths from a given source to every other
// vertex using BFS.
#include
using namespace std;
// Traverses graph in BFS manner. It fills
// dist[] and paths[]
void BFS(vector adj[], int src, int dist[],
int paths[], int n)
{
bool visited[n];
for (int i = 0; i < n; i++)
visited[i] = false;
dist[src] = 0;
paths[src] = 1;
queue q;
q.push(src);
visited[src] = true;
while (!q.empty())
{
int curr = q.front();
q.pop();
// For all neighbors of current vertex do:
for (auto x : adj[curr])
{
// if the current vertex is not yet
// visited, then push it to the queue.
if (visited[x] == false)
{
q.push(x);
visited[x] = true;
}
// check if there is a better path.
if (dist[x] > dist[curr] + 1)
{
dist[x] = dist[curr] + 1;
paths[x] = paths[curr];
}
// additional shortest paths found
else if (dist[x] == dist[curr] + 1)
paths[x] += paths[curr];
}
}
}
// function to find number of different
// shortest paths form given vertex s.
// n is number of vertices.
void findShortestPaths(vector adj[],
int s, int n)
{
int dist[n], paths[n];
for (int i = 0; i < n; i++)
dist[i] = INT_MAX;
for (int i = 0; i < n; i++)
paths[i] = 0;
BFS(adj, s, dist, paths, n);
cout << "Numbers of shortest Paths are: ";
for (int i = 0; i < n; i++)
cout << paths[i] << " ";
}
// A utility function to add an edge in a
// directed graph.
void addEdge(vector adj[], int u, int v)
{
adj[u].push_back(v);
}
// Driver code
int main()
{
int n = 7; // Number of vertices
vector adj[n];
addEdge(adj, 0, 1);
addEdge(adj, 0, 2);
addEdge(adj, 1, 2);
addEdge(adj, 1, 3);
addEdge(adj, 2, 3);
addEdge(adj, 3, 4);
addEdge(adj, 3, 5);
addEdge(adj, 4, 6);
addEdge(adj, 5, 6);
findShortestPaths(adj, 0, 7);
return 0;
}
Java
// Java program to count number of shortest
// paths from a given source to every other
// vertex using BFS.
import java.io.*;
import java.util.*;
class GFG
{
// Traverses graph in BFS manner.
// It fills dist[] and paths[]
static void BFS(Vector[] adj, int src,
int dist[], int paths[], int n)
{
boolean[] visited = new boolean[n];
for (int i = 0; i < n; i++)
visited[i] = false;
dist[src] = 0;
paths[src] = 1;
Queue q = new LinkedList<>();
q.add(src);
visited[src] = true;
while (!q.isEmpty())
{
int curr = q.peek();
q.poll();
// For all neighbors of current vertex do:
for (int x : adj[curr])
{
// if the current vertex is not yet
// visited, then push it to the queue.
if (visited[x] == false)
{
q.add(x);
visited[x] = true;
}
// check if there is a better path.
if (dist[x] > dist[curr] + 1)
{
dist[x] = dist[curr] + 1;
paths[x] = paths[curr];
}
// additional shortest paths found
else if (dist[x] == dist[curr] + 1)
paths[x] += paths[curr];
}
}
}
// function to find number of different
// shortest paths form given vertex s.
// n is number of vertices.
static void findShortestPaths(Vector adj[],
int s, int n)
{
int[] dist = new int[n], paths = new int[n];
for (int i = 0; i < n; i++)
dist[i] = Integer.MAX_VALUE;
for (int i = 0; i < n; i++)
paths[i] = 0;
BFS(adj, s, dist, paths, n);
System.out.print("Numbers of shortest Paths are: ");
for (int i = 0; i < n; i++)
System.out.print(paths[i] + " ");
}
// A utility function to add an edge in a
// directed graph.
static void addEdge(Vector adj[],
int u, int v)
{
adj[u].add(v);
}
// Driver Code
public static void main(String[] args)
{
int n = 7; // Number of vertices
Vector[] adj = new Vector[n];
for (int i = 0; i < n; i++)
adj[i] = new Vector<>();
addEdge(adj, 0, 1);
addEdge(adj, 0, 2);
addEdge(adj, 1, 2);
addEdge(adj, 1, 3);
addEdge(adj, 2, 3);
addEdge(adj, 3, 4);
addEdge(adj, 3, 5);
addEdge(adj, 4, 6);
addEdge(adj, 5, 6);
findShortestPaths(adj, 0, 7);
}
}
// This code is contributed by
// sanjeev2552
Python3
# Python3 program to count number of shortest
# paths from a given source to every other
# vertex using BFS.
from collections import deque
from sys import maxsize as INT_MAX
# Traverses graph in BFS manner. It fills
# dist[] and paths[]
def BFS(adj: list, src: int, dist: list, paths: list, n: int):
visited = [False] * n
dist[src] = 0
paths[src] = 1
q = deque()
q.append(src)
visited[src] = True
while q:
curr = q[0]
q.popleft()
# For all neighbors of current vertex do:
for x in adj[curr]:
# if the current vertex is not yet
# visited, then push it to the queue.
if not visited[x]:
q.append(x)
visited[x] = True
# check if there is a better path.
if dist[x] > dist[curr] + 1:
dist[x] = dist[curr] + 1
paths[x] = paths[curr]
# additional shortest paths found
elif dist[x] == dist[curr] + 1:
paths[x] += paths[curr]
# function to find number of different
# shortest paths form given vertex s.
# n is number of vertices.
def findShortestPaths(adj: list, s: int, n: int):
dist = [INT_MAX] * n
paths = [0] * n
BFS(adj, s, dist, paths, n)
print("Numbers of shortest Paths are:", end=" ")
for i in paths:
print(i, end=" ")
# A utility function to add an edge in a
# directed graph.
def addEdge(adj: list, u: int, v: int):
adj[u].append(v)
# Driver Code
if __name__ == "__main__":
n = 7 # Number of vertices
adj = [0] * n
for i in range(n):
adj[i] = []
addEdge(adj, 0, 1)
addEdge(adj, 0, 2)
addEdge(adj, 1, 2)
addEdge(adj, 1, 3)
addEdge(adj, 2, 3)
addEdge(adj, 3, 4)
addEdge(adj, 3, 5)
addEdge(adj, 4, 6)
addEdge(adj, 5, 6)
findShortestPaths(adj, 0, 7)
# This code is contributed by
# sanjeev2552
C#
// C# program to count number of shortest
// paths from a given source to every other
// vertex using BFS.
using System;
using System.Collections.Generic;
class GFG
{
// Traverses graph in BFS manner.
// It fills dist[] and paths[]
static void BFS(List[] adj, int src,
int []dist, int []paths, int n)
{
bool[] visited = new bool[n];
for (int i = 0; i < n; i++)
visited[i] = false;
dist[src] = 0;
paths[src] = 1;
List q = new List();
q.Add(src);
visited[src] = true;
while (q.Count != 0)
{
int curr = q[0];
q.RemoveAt(0);
// For all neighbors of current vertex do:
foreach (int x in adj[curr])
{
// if the current vertex is not yet
// visited, then push it to the queue.
if (visited[x] == false)
{
q.Add(x);
visited[x] = true;
}
// check if there is a better path.
if (dist[x] > dist[curr] + 1)
{
dist[x] = dist[curr] + 1;
paths[x] = paths[curr];
}
// additional shortest paths found
else if (dist[x] == dist[curr] + 1)
paths[x] += paths[curr];
}
}
}
// function to find number of different
// shortest paths form given vertex s.
// n is number of vertices.
static void findShortestPaths(List []adj,
int s, int n)
{
int[] dist = new int[n], paths = new int[n];
for (int i = 0; i < n; i++)
dist[i] = int.MaxValue;
for (int i = 0; i < n; i++)
paths[i] = 0;
BFS(adj, s, dist, paths, n);
Console.Write("Numbers of shortest Paths are: ");
for (int i = 0; i < n; i++)
Console.Write(paths[i] + " ");
}
// A utility function to add an edge in a
// directed graph.
static void addEdge(List []adj,
int u, int v)
{
adj[u].Add(v);
}
// Driver Code
public static void Main(String[] args)
{
int n = 7; // Number of vertices
List[] adj = new List[n];
for (int i = 0; i < n; i++)
adj[i] = new List();
addEdge(adj, 0, 1);
addEdge(adj, 0, 2);
addEdge(adj, 1, 2);
addEdge(adj, 1, 3);
addEdge(adj, 2, 3);
addEdge(adj, 3, 4);
addEdge(adj, 3, 5);
addEdge(adj, 4, 6);
addEdge(adj, 5, 6);
findShortestPaths(adj, 0, 7);
}
}
// This code is contributed by 29AjayKumar
Javascript
Numbers of shortest Paths are: 1 1 1 2 2 2 4
时间复杂度:O(V + E)