Algoteka
Log in to submit your own samples!

Dijkstra's Shortest Path Algorithm

Problem by oml1111
# Tech tags Title Creator Created date
1 0
2022-07-30 01:54
View all samples for this language (1 verified and 0 unverified)

|V| log |V| solution using STL heap | C++ |

By oml1111 |
0 likes

An \(O(|E| + |V| \log |V|)\) algorithm that finds the distance from the starting vertex on a weighted graph (\(|V|\) is no. of vertices, \(|E|\) is no. of edges). Implemented for integer edge weights, but can be trivially adapted to account for floating-point edge weights.

Code

#include<vector>
#include<deque>
#include<tuple>
#include<queue>

struct DijkstraGraph {
    struct Node;
    struct Arc {
        Node* dest;
        int l;
    };
    struct Node {
        std::vector<Arc> arc;
        bool explr = false;
        long long dist;
    };
    std::deque<Node> nodes;
    
    Node* add_node() {
        nodes.push_back(Node());
        return &nodes.back();
    }
    void add_edge(Node* u, Node* v, int l) {
        u->arc.push_back({v, l});
    }
    
    void dijkstra(Node* start) {
        std::priority_queue<std::pair<long long, Node*> > frontier;
        frontier.push({0, start});
        
        while(frontier.size() > 0) {
            long long potential;
            Node* cur;
            std::tie(potential, cur) = frontier.top();
            potential = -potential;
            frontier.pop();
            
            if(!cur->explr) {
                cur->explr = true;
                cur->dist = potential;
                
                for(Arc curArc : cur->arc) {
                    // priority_queue is a max-heap, so for convenience we use the negative of potential instead of
                    // defining a custom ordering function
                    frontier.push({-potential - curArc.l, curArc.dest});
                }
            }
        }
    }
};

int main() {
    DijkstraGraph graph;
    
    graph.add_node();
    graph.add_node();
    graph.add_edge(&graph.nodes[0], &graph.nodes[1], 5);
    // ...
    // Populate the graph with add_node and add_edge
    
    graph.dijkstra(&graph.nodes[0]); // Assumes node 0 is where we start the search
}

Further reading

Basic Graph Algorithms: Dijkstra's algorithm - courses.cs.ut.ee
Dijkstra's algorithm - wikipedia.org

References

classes
std::deque en.cppreference.com cplusplus.com
std::pair en.cppreference.com cplusplus.com
std::priority_queue en.cppreference.com cplusplus.com
std::vector en.cppreference.com cplusplus.com
functions
std::deque::push_back en.cppreference.com cplusplus.com
std::pair::pair en.cppreference.com cplusplus.com
std::priority_queue::pop en.cppreference.com cplusplus.com
std::priority_queue::push en.cppreference.com cplusplus.com
std::priority_queue::top en.cppreference.com cplusplus.com
std::tie en.cppreference.com cplusplus.com
std::vector::push_back en.cppreference.com cplusplus.com

Problem Description

Construct a weighted directed graph and perform Dijkstra's shortest path algorithm on it. Calculate the distance of each node from the starting vertex of the search.

View sample discussion (0 comments)
View problem discussion (0 comments)