📜  c++ geeksforgeeks 中的 dijkstra 算法 - C++ (1)

📅  最后修改于: 2023-12-03 14:39:49.768000             🧑  作者: Mango

C++ GeeksForGeeks 中的 Dijkstra 算法

Dijkstra 算法是一种用于解决带有非负边权的最短路问题的贪心算法。它以一个顶点作为起点(源点)并找到到达所有其他顶点的最短路径。该算法最初由荷兰计算机科学家 Edsger W. Dijkstra 在1956年发明。

算法步骤
  1. 创建数据结构来存储图的边和距离
  2. 初始化源点的距离为0,将其它节点的距离设为无限大
  3. 选择具有最小距离的顶点,并找到到达该顶点的所有边
  4. 对于每个相邻节点,将距离值更新为:源节点到该节点的距离 + 该节点到相邻节点的边权重
  5. 标记已经访问的顶点
  6. 重复步骤3-5直到找到所有节点的最短路径
C++ 实现

下面是使用 C++ 编程语言实现 Dijkstra 算法的示例代码。

// C++ code for Dijkstra's shortest 
// path algorithm using priority_queue 
#include<bits/stdc++.h> 
using namespace std; 
# define INF 0x3f3f3f3f 

// typedef to shorten the code 
typedef pair<int, int> iPair; 

// This class represents a directed graph using 
// adjacency list representation 
class Graph 
{ 
    int V; // Number of vertices 
    list< pair<int, int> > *adj; 

public: 
    Graph(int V) // Constructor 
    { 
        this->V = V; 
        adj = new list<iPair> [V]; 
    } 

    // function to add an edge to the graph 
    void addEdge(int u, int v, int w) 
    { 
        adj[u].push_back(make_pair(v, w)); 
        adj[v].push_back(make_pair(u, w)); 
    } 

    // prints shortest path from s 
    void shortestPath(int s) 
    { 
        // Create a priority queue to store vertices that 
        // are being preprocessed. This is weird syntax in C++. 
        // Refer below link for details of this syntax 
        // https://www.geeksforgeeks.org/implement-min-heap-using-stl/ 
        priority_queue< iPair, vector <iPair> , greater<iPair> > pq; 

        // Create a vector for distances and initialize all 
        // distances as infinite (INF) 
        vector<int> dist(V, INF); 

        // Insert source itself in priority queue and initialize 
        // its distance as 0. 
        pq.push(make_pair(0, s)); 
        dist[s] = 0; 

        /* Looping till priority queue becomes empty (or all 
          distances are not finalized) */
        while (!pq.empty()) 
        { 
            // The first vertex in pair is the minimum distance 
            // vertex, extract it from priority queue. 
            // vertex label is stored in second of pair (it 
            // has to be done this way to keep the vertices 
            // sorted distance (distance must be first item 
            // in pair) 
            int u = pq.top().second; 
            pq.pop(); 

            // 'i' is used to get all adjacent vertices of a vertex 
            list< pair<int, int> >::iterator i; 
            for (i = adj[u].begin(); i != adj[u].end(); ++i) 
            { 
                // Get vertex label and weight of current adjacent 
                // of u. 
                int v = (*i).first; 
                int weight = (*i).second; 

                // If there is shorted path to v through u. 
                if (dist[v] > dist[u] + weight) 
                { 
                    // Updating distance of v 
                    dist[v] = dist[u] + weight; 
                    pq.push(make_pair(dist[v], v)); 
                } 
            } 
        } 

        // Print shortest distances stored in dist[] 
        printf("Vertex   Distance from Source\n"); 
        for (int i = 0; i < V; ++i) {
            if(dist[i] != INF) {
                printf("%d \t\t %d\n", i, dist[i]); 
            } else {
                printf("%d \t\t not reachable\n", i); 
            }
        }
    } 
}; 

int main() 
{ 
    // create the graph given in above figure 
    int V = 9; 
    Graph g(V); 

    // making above shown graph 
    g.addEdge(0, 1, 4); 
    g.addEdge(0, 7, 8); 
    g.addEdge(1, 2, 8); 
    g.addEdge(1, 7, 11); 
    g.addEdge(2, 3, 7); 
    g.addEdge(2, 8, 2); 
    g.addEdge(2, 5, 4); 
    g.addEdge(3, 4, 9); 
    g.addEdge(3, 5, 14); 
    g.addEdge(4, 5, 10); 
    g.addEdge(5, 6, 2); 
    g.addEdge(6, 7, 1); 
    g.addEdge(6, 8, 6); 
    g.addEdge(7, 8, 7); 

    g.shortestPath(0); 

    return 0; 
} 

此段代码使用邻接列表来表示图,并使用堆栈进行优先队列的处理。它使用重载操作符和pair将顶点和它们之间的边表示为权值对。我们可以将Dijkstra的最短路径算法应用于此邻接列表,然后通过打印最短路径来将结果显示出来。

参考