A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://www.geeksforgeeks.org/dsa/dials-algorithm-optimized-dijkstra-for-small-range-weights/ below:

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

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

Last Updated : 23 Jul, 2025

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.

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:
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
// Java program to find Shortest Path using Dial's Algorithm

import java.util.*;

class GfG {
    
    // Function to find Shortest Path
    static int[] shortestPath(int n, int src, int[][] edges) {
        ArrayList<ArrayList<ArrayList<Integer>>> adj = new ArrayList<>();
        int maxWeight = 0;
        
        // Build adjacency list and find maximum weight
        for (int i = 0; i < n; i++) {
            adj.add(new ArrayList<>());
        }
        for (int[] e : edges) {
            ArrayList<Integer> edge1 = new ArrayList<>();
            edge1.add(e[1]);
            edge1.add(e[2]);
            adj.get(e[0]).add(edge1);
            
            ArrayList<Integer> edge2 = new ArrayList<>();
            edge2.add(e[0]);
            edge2.add(e[2]);
            adj.get(e[1]).add(edge2);
            
            maxWeight = Math.max(maxWeight, e[2]);
        }
        
        // Initialize distance array
        int[] dist = new int[n];
        Arrays.fill(dist, Integer.MAX_VALUE);
        dist[src] = 0;
        
        // Create buckets for distances
        int maxDist = (n - 1) * maxWeight;
        ArrayList<HashSet<Integer>> buckets = new ArrayList<>(maxDist + 1);
        for (int i = 0; i <= maxDist; i++) {
            buckets.add(new HashSet<>());
        }
        
        // Add source to bucket 0
        buckets.get(0).add(src);
        
        // Process buckets in order
        for (int d = 0; d <= maxDist; d++) {
            
            // Process all nodes in current bucket
            while (!buckets.get(d).isEmpty()) {
                int u = buckets.get(d).iterator().next();
                buckets.get(d).remove(u);
                
                // Skip if we already found a better path
                if (d > dist[u]) continue;
                
                // Process all adjacent nodes
                for (ArrayList<Integer> edge : adj.get(u)) {
                    int v = edge.get(0);
                    int weight = edge.get(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] != Integer.MAX_VALUE) {
                            buckets.get(dist[v]).remove(v);
                        }
                        
                        // Update distance and add to new bucket
                        dist[v] = newDist;
                        buckets.get(newDist).add(v);
                    }
                }
            }
        }
        
        return dist;
    }

    public static void main(String[] args) {
        int n = 9;
        int src = 0;
        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}
        };
        
        int[] res = shortestPath(n, src, edges);
        for (int val : res) {
            System.out.print(val + " ");
        }
        System.out.println();
    }
}
Python
# Python program to find Shortest Path using Dial's Algorithm

import sys
from collections import defaultdict

def shortestPath(n, src, edges):
    adj = [[] for _ in range(n)]
    maxWeight = 0
    
    # Build adjacency list and find maximum weight
    for e in edges:
        adj[e[0]].append([e[1], e[2]])
        adj[e[1]].append([e[0], e[2]])
        maxWeight = max(maxWeight, e[2])
    
    # Initialize distance array
    dist = [sys.maxsize] * n
    dist[src] = 0
    
    # Create buckets for distances
    maxDist = (n - 1) * maxWeight
    buckets = defaultdict(set)
    
    # Add source to bucket 0
    buckets[0].add(src)
    
    # Process buckets in order
    for d in range(maxDist + 1):
        # Process all nodes in current bucket
        while d in buckets and buckets[d]:
            u = buckets[d].pop()
            
            # Skip if we already found a better path
            if d > dist[u]:
                continue
            
            # Process all adjacent nodes
            for edge in adj[u]:
                v, weight = edge[0], edge[1]
                newDist = dist[u] + weight
                
                # If shorter path found
                if newDist < dist[v]:
                    # Remove from old bucket if it was there
                    if dist[v] != sys.maxsize:
                        buckets[dist[v]].discard(v)
                    
                    # Update distance and add to new bucket
                    dist[v] = newDist
                    buckets[newDist].add(v)
    
    return dist

if __name__ == "__main__":
    n = 9
    src = 0
    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]
    ]
    
    res = shortestPath(n, src, edges)
    for val in res:
        print(val, end=" ")
    print()
C#
// C# program to find Shortest Path using Dial's Algorithm

using System;
using System.Collections.Generic;

class GfG {
    
    // Function to find Shortest Path
    static int[] shortestPath(int n, int src, int[][] edges) {
        List<List<List<int>>> adj = new List<List<List<int>>>();
        int maxWeight = 0;
        
        // Build adjacency list and find maximum weight
        for (int i = 0; i < n; i++) {
            adj.Add(new List<List<int>>());
        }
        foreach (int[] e in edges) {
            adj[e[0]].Add(new List<int> {e[1], e[2]});
            adj[e[1]].Add(new List<int> {e[0], e[2]});
            maxWeight = Math.Max(maxWeight, e[2]);
        }
        
        // Initialize distance array
        int[] dist = new int[n];
        Array.Fill(dist, int.MaxValue);
        dist[src] = 0;
        
        // Create buckets for distances
        int maxDist = (n - 1) * maxWeight;
        List<HashSet<int>> buckets = new List<HashSet<int>>(maxDist + 1);
        for (int i = 0; i <= maxDist; i++) {
            buckets.Add(new HashSet<int>());
        }
        
        // Add source to bucket 0
        buckets[0].Add(src);
        
        // Process buckets in order
        for (int d = 0; d <= maxDist; d++) {
            
            // Process all nodes in current bucket
            while (buckets[d].Count > 0) {
                int u = 0;
                foreach (int node in buckets[d]) {
                    u = node;
                    break;
                }
                buckets[d].Remove(u);
                
                // Skip if we already found a better path
                if (d > dist[u]) continue;
                
                // Process all adjacent nodes
                foreach (List<int> edge in 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.MaxValue) {
                            buckets[dist[v]].Remove(v);
                        }
                        
                        // Update distance and add to new bucket
                        dist[v] = newDist;
                        buckets[newDist].Add(v);
                    }
                }
            }
        }
        
        return dist;
    }

    static void Main() {
        int n = 9;
        int src = 0;
        int[][] edges = new int[][] {
            new int[] {0, 1, 4},
            new int[] {0, 7, 8},
            new int[] {1, 2, 8},
            new int[] {1, 7, 11},
            new int[] {2, 3, 7},
            new int[] {2, 8, 2},
            new int[] {3, 4, 9},
            new int[] {3, 5, 14},
            new int[] {4, 5, 10},
            new int[] {5, 6, 2},
            new int[] {6, 7, 1},
            new int[] {6, 8, 6},
            new int[] {7, 8, 7}
        };
        
        int[] res = shortestPath(n, src, edges);
        foreach (int val in res) {
            Console.Write(val + " ");
        }
        Console.WriteLine();
    }
}
JavaScript
// Js program to find Shortest Path using Dial's Algorithm

function shortestPath(n, src, edges) {
    const adj = Array.from({length: n}, () => []);
    let maxWeight = 0;
    
    // Build adjacency list and find maximum weight
    for (const e of edges) {
        adj[e[0]].push([e[1], e[2]]);
        adj[e[1]].push([e[0], e[2]]);
        maxWeight = Math.max(maxWeight, e[2]);
    }
    
    // Initialize distance array
    const dist = new Array(n).fill(Infinity);
    dist[src] = 0;
    
    // Create buckets for distances
    const maxDist = (n - 1) * maxWeight;
    const buckets = Array.from({length: maxDist + 1}, () => new Set());
    
    // Add source to bucket 0
    buckets[0].add(src);
    
    // Process buckets in order
    for (let d = 0; d <= maxDist; d++) {
        
        // Process all nodes in current bucket
        while (buckets[d].size > 0) {
            const u = buckets[d].values().next().value;
            buckets[d].delete(u);
            
            // Skip if we already found a better path
            if (d > dist[u]) continue;
            
            // Process all adjacent nodes
            for (const edge of adj[u]) {
                const [v, weight] = edge;
                const newDist = dist[u] + weight;
                
                // If shorter path found
                if (newDist < dist[v]) {
                    
                    // Remove from old bucket if it was there
                    if (dist[v] !== Infinity) {
                        buckets[dist[v]].delete(v);
                    }
                    
                    // Update distance and add to new bucket
                    dist[v] = newDist;
                    buckets[newDist].add(v);
                }
            }
        }
    }
    
    return dist;
}

const n = 9;
const src = 0;
const 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]
];

const res = shortestPath(n, src, edges);
console.log(res.join(' '));

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: Disadvantages:
Similar Reads

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4