Dijkstra's Shortest path Algorithm

Introduction:

This is a single source shortest path Algorithm where there is a single source from which we want to find shortest path to a node or to all other nodes.

Problem Statement:

find the shortest paths to all nodes from a start node.

Algorithm

1. A graph \(G(V, E)\) and start vertex \(s\) are given.

2. We create vertex set containing all vertices.

3. we have two arrays \(dist[\ ]\) initialized to \(\infty\) and \(prev[\ ]\) initilaized to -1 for all vertices

4. we make \(dist[s] = 0\).

5. while queue is not empty we pop vertex \(u\) from queue which has shortest value for \(dist[u]\).

6. for each vertex v in adjacency_list of u and in queue check if dist[v] can be relaxed i.e., check if \(dist[u]+ weightofedge(u, v) < dist[v]\) and accordingly update dist[v]

Pseudo code :

(source wikipedia)

function Dijkstra(Graph, source):
    dist[source] ← 0                           // Initialization

    create vertex priority queue Q

    for each vertex v in Graph:          
        if v ≠ source
            dist[v] ← INFINITY                 // Unknown distance from source to v
            prev[v] ← UNDEFINED                // Predecessor of v

        Q.add_with_priority(v, dist[v])


    while Q is not empty:                      // The main loop
        u ← Q.extract_min()                    // Remove and return best vertex
        for each neighbor v of u:              // only v that are still in Q
            alt ← dist[u] + length(u, v)
            if alt < dist[v]
                dist[v] ← alt
                prev[v] ← u
                Q.decrease_priority(v, alt)

     return dist, prev
    

Code :

    // single source shortest path
    // no negative edges
    #include <bits/stdc++.h>
    using namespace std;
    
    #define adjacency_list map<int, vector<pair<int, int>>>
    #define mp make_pair
    #define INF INT_MAX
    
    typedef struct graph
    {
        adjacency_list adj;
        int num_edges;
        int num_vertices;
    } graph;
    
    void dijkstra(graph G, int source)
    {
        set<int> vertex_set;
        for (int i = 0; i < G.num_vertices; i++)
        {
            vertex_set.insert(i);
        }
        vector<int> dist(G.num_vertices, INF);
        vector<int> prev(G.num_vertices, -1);
    
        dist[source] = 0;
        while (!vertex_set.empty())
        {
            int u = *(vertex_set.begin());
            int min_dist = INF;
            for (auto i : vertex_set)
            {
                if (dist[i] < min_dist)
                {
                    u = i;
                    min_dist = dist[i];
                }
            }
            vertex_set.erase(u);
            // u has vertex with min distance from source
            // terminate dijkstra if you want minimum distance to this vertex.
            for (auto i : G.adj[u])
            {
                int v = i.first;
                if (dist[u] != INF && dist[u] + i.second < dist[v])
                {
                    dist[v] = dist[u] + i.second;
                    prev[v] = u;
                }
            }
        }
        cout << "vertex prev dist\n";
    
        for (int i = 0; i < G.num_vertices; i++)
        {
            cout << i << " " << prev[i] << " " << dist[i] << "\n";
        }
        // cout << "\n";
    }
    
    int main()
    {
        // undirected graph
    
        graph G; // u - {{v1,w1}, {v2, w2}, .... {vk,wk}}
        cin >> G.num_vertices;
        cin >> G.num_edges;
    
        int u, v, w;
        for (int i = 0; i < G.num_edges; i++)
        {
            cin >> u >> v >> w;
            G.adj[u].push_back(mp(v, w));
            G.adj[v].push_back(mp(u, w)); // comment this if directed.
        }
        int s;
        // cout << "Enter start vertext for dijkstra : ";
        cin >> s;
    
        dijkstra(G, s);
        // cout << "\n";
    }
                  
    

Complexity Analysis :

Time complexity : \(O(|V|^2)\) . This is the original dijkstra's algorithm which does not use min-heap to get min distance.

Try using min heap in the above implementation.

Complexity dependends on the implementation of this algorithm. \(O(|E|T_{decrease\_key}+|V|T_{extract\_min})\)

video resources

web resources

Dijkstra wikipedia

sum of logx

book resources