📌  相关文章
📜  加权和有向图中从节点 1 到 N 的不同最短路径的数量

📅  最后修改于: 2021-10-25 05:10:06             🧑  作者: Mango

给定 N 个节点和M 条边的有向加权图,任务是计算节点1N 之间最短路径的数量。

例子:

方法:该问题可以通过 Dijkstra 算法解决。使用两个数组,比如dist[]来存储到源顶点的最短距离和大小为N 的路径 [] ,来存储从源顶点到顶点N的不同最短路径的数量。请按照以下步骤操作。

  • 初始化一个优先级队列,比如pq,来存储顶点数和它的距离值。
  • 初始化一个零向量,比如大小为N 的路径 [] ,并使路径 [1]等于1
  • 初始化一个大数向量 (1e9),比如大小为N 的dist[] ,并使dist[1]等于0
  • pq不为空时迭代。
    • pq 中弹出并将顶点值存储在一个变量中,比如u ,并将距离值存储在变量d 中
    • 如果d大于u ,则继续
    • 对于每个顶点u 的每个 v ,如果dist[v] > dist[u]+(u 和 v 的边成本),则将dist[v] 减少到 dist[u] +(u 和 v 的边成本)将顶点 u的路径数分配给顶点 v的路径数。
    • 对于每个顶点u 的每个 v ,如果dist[v] = dist[u] + (u 和 v 的边成本) ,则将顶点u的路径数与顶点v的路径数相加。
  • 最后,打印路径[N]。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
  
const int INF = 1e9;
const int MAXN = 1e5 + 1;
vector > > g(MAXN);
vector dist(MAXN);
vector route(MAXN);
  
// Function to count number of shortest
// paths from node 1 to node N
void countDistinctShortestPaths(
    int n, int m, int edges[][3])
{
    // Storing the graph
    for (int i = 0; i < m; ++i) {
        int u = edges[i][0],
            v = edges[i][1],
            c = edges[i][2];
        g[u].push_back({ v, c });
    }
  
    // Initializing dis array to a
    // large value
    for (int i = 2; i <= n; ++i) {
        dist[i] = INF;
    }
  
    // Initialize a priority queue
    priority_queue,
                   vector >,
                   greater > >
        pq;
    pq.push({ 0, 1 });
  
    // Base Cases
    dist[1] = 0;
    route[1] = 1;
  
    // Loop while priority queue is
    // not empty
    while (!pq.empty()) {
        int d = pq.top().first;
        int u = pq.top().second;
        pq.pop();
  
        // if d is greater than distance
        // of the node
        if (d > dist[u])
            continue;
  
        // Traversing all its neighbours
        for (auto e : g[u]) {
            int v = e.first;
            int c = e.second;
            if (c + d > dist[v])
                continue;
  
            // Path found of same distance
            if (c + d == dist[v]) {
                route[v] += route[u];
            }
  
            // New path found for lesser
            // distance
            if (c + d < dist[v]) {
                dist[v] = c + d;
                route[v] = route[u];
  
                // Pushing in priority
                // queue
                pq.push({ dist[v], v });
            }
        }
    }
}
  
// Driver Code
int main()
{
    // Given Input
    int n = 4;
    int m = 5;
    int edges[m][3] = { { 1, 4, 5 },
                        { 1, 2, 4 },
                        { 2, 4, 5 },
                        { 1, 3, 2 },
                        { 3, 4, 3 } };
  
    // Function Call
    countDistinctShortestPaths(n, m, edges);
    cout << route[n] << endl;
  
    return 0;
}


输出:
2

时间复杂度: O(MLogN)
辅助空间: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。