Dijkstra Heap Algorithm

The Dijkstra Heap Algorithm, also known as Dijkstra's shortest path algorithm, is a widely used graph search algorithm that finds the shortest path between nodes in a weighted graph. The algorithm was conceived by the computer scientist Edsger W. Dijkstra in 1956 and has since been applied in numerous applications, such as network routing protocols, navigation systems, and traffic simulations. It works by exploring the graph in a breadth-first manner while maintaining a priority queue (often implemented as a binary heap) to store the vertices ordered by their distance from the source node. The algorithm repeatedly selects the vertex with the lowest distance value, updates the distance values of its neighbors, and adds them to the priority queue until it reaches the target node or all nodes have been visited. Dijkstra's algorithm begins by initializing the distance value of the source node to zero and the distance values of all other nodes to infinity, as well as marking all nodes as unvisited. The algorithm then proceeds by selecting the unvisited node with the smallest distance value and updating the distances of its neighbors by considering the weight of the edges connecting them. If the calculated distance of a neighbor through the current node is smaller than its current distance value, the neighbor's distance value is updated, and the neighbor is added to the priority queue. This process is repeated until the target node is visited or all nodes have been processed. Once the algorithm is complete, the shortest path can be reconstructed by tracing the path from the target node back to the source node using the updated distance values. The algorithm's time complexity is O(|V|^2) for a simple implementation, but it can be significantly reduced to O(|V| + |E| log |V|) by using a binary heap or Fibonacci heap to optimize the priority queue operations.
/**************************************************************************************

    Dijkstra on heap for sparse graphs - O(MlogM)
    Based on problem 20C from codeforces: http://codeforces.ru/contest/20/problem/C

**************************************************************************************/

#include <iostream>
#include <fstream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <cassert>
#include <utility>
#include <iomanip>

using namespace std;

const long long INF = (long long) 1e12;
const int MAXN = 105000;

struct edge {
    int to, w;
};

int n, m;
vector <edge> g[MAXN];
long long dist[MAXN];
int par[MAXN];
priority_queue < pair<long long, int> > q;
vector <int> ans;
edge e;

int main() {
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= m; i++) {
        int a, b, w;
        scanf("%d %d %d", &a, &b, &w);
        e.to = b; e.w = w;
        g[a].push_back(e);
        e.to = a;
        g[b].push_back(e);
    }

    q.push(make_pair(0, 1));
    for (int i = 2; i <= n; i++) {
        dist[i] = INF;
        q.push(make_pair(-INF, i));
    }

    while (!q.empty()) {
        int cur = q.top().second;
        long long cur_dist = -q.top().first;
        q.pop();
        if (cur_dist > dist[cur])
            continue;
        for (int i = 0; i < (int) g[cur].size(); i++) {
            int to = g[cur][i].to, w = g[cur][i].w;
            if (cur_dist + w < dist[to]) {
                dist[to] = cur_dist + w;
                par[to] = cur;
                q.push(make_pair(-dist[to], to));
            }
        }
    }

    if (dist[n] == INF) {
        printf("-1");
        return 0;
    }

    int cur = n;
    while (par[cur] != 0) {
        ans.push_back(cur);
        cur = par[cur];
    }
    ans.push_back(1);

    reverse(ans.begin(), ans.end());
    for (int i = 0; i < (int) ans.size(); i++)
        printf("%d ", ans[i]);

    return 0;
}

LANGUAGE:

DARK MODE: