(Translated by https://www.hiragana.jp/)
Dial's Algorithm (Optimized Dijkstra for small range weights) - GeeksforGeeks
Open In App

Dial's Algorithm (Optimized Dijkstra for small range weights)

Last Updated : 23 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a weighted Graph and a source vertex, the task is to find the shortest paths from the source node to all other vertices.

Example:

Input : n = 9, src = 0

Output : 0 4 12 19 21 11 9 8 14

We have learned about how to find the shortest path from a given source vertex to all other vertex using Dijkstra's shortest path algorithm with the Time Complexity of O(E log V) in this article.

Can we optimize Dijkstra's shortest path algorithm to work better than O(E log V) if the maximum weight is small (or the range of edge weights is small)? 

For example, in the above diagram, the maximum weight is 14. Many times the range of weights on edges is in a small range (i.e. all edge weights can be mapped to 0, 1, 2.. W where W is a small number). In that case, Dijkstra’s algorithm can be modified by using different data structures, and buckets, which is called dial implementation of Dijkstra's algorithm. time complexity is O(E + WV) where W is the maximum weight on any edge of the graph, so we can see that, if W is small then this implementation runs much faster than the traditional algorithm. 

The following are important observations.

  • The maximum distance between any two nodes can be at max w(V – 1) (w is maximum edge weight and we can have at max V-1 edges between two vertices).
  • In the Dijkstra algorithm, distances are finalized in non-decreasing, i.e., the distance of the closer (to given source) vertices is finalized before the distant vertices.

Approach:

The idea is to use bucket based optimization for Dijkstra's algorithm when edge weights are small integers. Instead of using a priority queue, we create buckets for each possible distance value and process nodes in distance order by iterating through buckets sequentially.

Step by step approach:

  1. Create buckets equal to maximum possible distance and initialize source distance as zero in first bucket.
  2. Iterate through buckets sequentially and process all nodes in current bucket:
    • For each node, examine all adjacent nodes and calculate new distance through current node.
    • If shorter path found, remove node from its current bucket and place in bucket corresponding to new distance.
C++
// C++ program to find Shortest Path using Dial's Algorithm
#include <bits/stdc++.h>
using namespace std;

// Function to find Shortest Path
vector<int> shortestPath(int n, int src, vector<vector<int>> &edges) {
    vector<vector<vector<int>>> adj(n);
    int maxWeight = 0;
    
    // Build adjacency list and find maximum weight
    for (auto e: edges) {
        adj[e[0]].push_back({e[1], e[2]});
        adj[e[1]].push_back({e[0], e[2]});
        maxWeight = max(maxWeight, e[2]);
    }
    
    // Initialize distance array
    vector<int> dist(n, INT_MAX);
    dist[src] = 0;
    
    // Create buckets for distances
    int maxDist = (n - 1) * maxWeight;
    vector<unordered_set<int>> buckets(maxDist + 1);
    
    // Add source to bucket 0
    buckets[0].insert(src);
    
    // Process buckets in order
    for (int d = 0; d <= maxDist; d++) {
        
        // Process all nodes in current bucket
        while (!buckets[d].empty()) {
            int u = *buckets[d].begin();
            buckets[d].erase(buckets[d].begin());
            
            // Skip if we already found a better path
            if (d > dist[u]) continue;
            
            // Process all adjacent nodes
            for (auto& edge : adj[u]) {
                int v = edge[0];
                int weight = edge[1];
                int newDist = dist[u] + weight;
                
                // If shorter path found
                if (newDist < dist[v]) {
                    
                    // Remove from old bucket if it was there
                    if (dist[v] != INT_MAX) {
                        buckets[dist[v]].erase(v);
                    }
                    
                    // Update distance and add to new bucket
                    dist[v] = newDist;
                    buckets[newDist].insert(v);
                }
            }
        }
    }
    
    return dist;
}

int main() {
    int n = 9;
    int src = 0;
    vector<vector<int>> edges = {
        {0, 1, 4},
        {0, 7, 8},
        {1, 2, 8},
        {1, 7, 11},
        {2, 3, 7},
        {2, 8, 2},
        {3, 4, 9},
        {3, 5, 14},
        {4, 5, 10},
        {5, 6, 2},
        {6, 7, 1},
        {6, 8, 6},
        {7, 8, 7}
    };
    
    vector<int> res = shortestPath(n, src, edges);
    for (auto val : res) {
        cout << val << " ";
    }
    cout << endl;
    return 0;
}
Java Python C# JavaScript

Output
0 4 12 19 21 11 9 8 14 

Time Complexity: O(V + E + W×V), where W is the maximum weight of an edge.
Space Complexity: O(V + W×V) for storing buckets and adjacency list.

Advantages:

  • Dial's algorithm can be much faster than Dijkstra's algorithm for graphs with small range weights.
  • It is easy to implement and modify from Dijkstra's algorithm.

Disadvantages:

  • Dial's algorithm is only applicable when the range of the edge weights is small. For graphs with large range weights, Dijkstra's algorithm may be faster.

Article Tags :
Practice Tags :

Similar Reads