📌  相关文章
📜  未加权和有向图中的最短路径数

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

未加权和有向图中的最短路径数

给定一个未加权的有向图,可以是循环的或非循环的。打印从给定顶点到每个顶点的最短路径数。例如,考虑下图。顶点 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)