Open In App

0-1 BFS (Shortest Path in a Binary Weight Graph)

Last Updated : 29 May, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an undirected graph where every edge has a weight as either 0 or 1. The task is to find the shortest path from the source vertex to all other vertices in the graph.

Example: 

Input: Source Vertex = 0 and below graph Having vertices like (u, v, w):
edges: [[0,1,0], [0, 7, 1], [1,2,1], [1, 7, 1], [2, 3, 0], [2, 5, 0], [2, 8, 1], [3, 4, 1],[3, 5, 1],[4, 5, 1],[5, 6, 1],[6, 7, 1],[7, 8, 1]]
Output: 0 0 1 1 2 1 2 1 2

[Naive Approach] Using Dijkstra Algorithm - O(E * log (V)) Time and O(V) Space

In Dijkstra's Algorithm, the goal is to find the shortest distance from a given source node to all other nodes in the graph. As the source node is the starting point, its distance is initialized to zero. From there, we iteratively pick the unprocessed node with the minimum distance from the source, this is where a min-heap (priority queue) or a set is typically used for efficiency.

Refer to Dijkstra's Algorithm to find Shortest Path for detailed explanation.

 [Expected Approach] Using Deque - O(V + E) time and O(V + E) space

The idea is to adapt BFS to efficiently handle graphs with binary weights (0 or 1) by using a deque instead of a queue. When we encounter an edge with weight 0, we add its destination to the front of the deque because it doesn't increase the distance. When we encounter an edge with weight 1, we add its destination to the back of the deque because it increases the distance by one unit.

Step by step approach:

  1. Initialize distances array with infinity for all vertices except source.
  2. Use a deque to process vertices in order of increasing distance.
  3. For each vertex, examine all adjacent vertices. If the new distance of vertex is less than current distance, then
    • If edge weight is 0, add adjacent vertex to front of deque (priority).
    • If edge weight is 1, add adjacent vertex to back of deque.

How it works?

The key property of the 0-1 BFS algorithm is that the deque maintains nodes in a very specific order. At any point during execution, the deque contains vertices with at most two consecutive distance values (d and d+1).

The deque will have a structure like [d, d, d, d, d+1, d+1, d+1], where all vertices with distance d appear before any vertex with distance d+1. This property is maintained because:

  1. When we encounter an edge with weight 0, we add the destination to the front of the deque (maintaining distance d)
  2. When we encounter an edge with weight 1, we add the destination to the back of the deque (creating distance d+1)

This ordering ensures that we process all vertices with distance d before processing any vertex with distance d+1. Furthermore, nodes with distance d+2 can only be added after all nodes with distance d have been processed (because they can only be reached through nodes with distance d+1).

C++
// C++ program to implement 0-1 BFS 
// (Shortest Path in a Binary Weight Graph)
#include <bits/stdc++.h>
using namespace std;

vector<int> minDist(int n, int src, vector<vector<int>> &edges) {
    
    // Create adjacency list representation of the graph
    vector<vector<vector<int>>> adj(n);
    for (auto &edge : edges) {
        int u = edge[0];
        int v = edge[1];
        int w = edge[2];
        adj[u].push_back({v, w});
        adj[v].push_back({u, w}); 
    }
    
    // Initialize distances to infinity
    vector<int> dist(n, INT_MAX);
    dist[src] = 0;
    
    // Use deque for 0-1 BFS
    deque<int> dq;
    dq.push_back(src);
    
    while (!dq.empty()) {
        int u = dq.front();
        dq.pop_front();
        
        // Process all adjacent vertices
        for (auto &edge : adj[u]) {
            int v = edge[0];
            int weight = edge[1];
            
            // If we can improve the distance
            if (dist[u] + weight < dist[v]) {
                dist[v] = dist[u] + weight;
                
                // If weight is 0, push to front (higher priority)
                // If weight is 1, push to back (lower priority)
                if (weight == 0)
                    dq.push_front(v);
                else
                    dq.push_back(v);
            }
        }
    }
    
    return dist;
}

int main() {
    int n = 9, src = 0;
    vector<vector<int>> edges = {
        {0, 1, 0}, {0, 7, 1}, {1, 2, 1}, {1, 7, 1}, 
        {2, 3, 0}, {2, 5, 0}, {2, 8, 1}, {3, 4, 1}, {3, 5, 1},
        {4, 5, 1}, {5, 6, 1}, {6, 7, 1}, {7, 8, 1}
    };
    
    vector<int> res = minDist(n, src, edges);
    for (int i = 0; i < n; i++) {
        cout << res[i] << " ";
    }
    cout << endl;
    
    return 0;
}
Java
// Java program to implement 0-1 BFS 
// (Shortest Path in a Binary Weight Graph)
import java.util.ArrayDeque;
import java.util.Deque;

class GfG {
    static int[] minDist(int n, int src, int[][] edges) {
        
        // Create adjacency list representation of the graph
        int[][][] adj = new int[n][][];
        int[] edgeCount = new int[n];
        
        // First pass to count edges per node
        for (int[] edge : edges) {
            int u = edge[0];
            int v = edge[1];
            edgeCount[u]++;
            edgeCount[v]++;
        }
        
        // Initialize adjacency lists
        for (int i = 0; i < n; i++) {
            adj[i] = new int[edgeCount[i]][2];
            edgeCount[i] = 0; // Reset to use as index
        }
        
        // Populate adjacency lists
        for (int[] edge : edges) {
            int u = edge[0];
            int v = edge[1];
            int w = edge[2];
            
            adj[u][edgeCount[u]++] = new int[]{v, w};
            adj[v][edgeCount[v]++] = new int[]{u, w};
        }
        
        // Initialize distances to infinity
        int[] dist = new int[n];
        for (int i = 0; i < n; i++) {
            dist[i] = Integer.MAX_VALUE;
        }
        dist[src] = 0;
        
        // Use deque for 0-1 BFS
        Deque<Integer> dq = new ArrayDeque<>();
        dq.addLast(src);
        
        while (!dq.isEmpty()) {
            int u = dq.removeFirst();
            
            // Process all adjacent vertices
            for (int[] edge : adj[u]) {
                int v = edge[0];
                int weight = edge[1];
                
                // If we can improve the distance
                if (dist[u] + weight < dist[v]) {
                    dist[v] = dist[u] + weight;
                    
                    // If weight is 0, push to front (higher priority)
                    // If weight is 1, push to back (lower priority)
                    if (weight == 0)
                        dq.addFirst(v);
                    else
                        dq.addLast(v);
                }
            }
        }
        
        return dist;
    }

    public static void main(String[] args) {
        int n = 9, src = 0;
        int[][] edges = {
            {0, 1, 0}, {0, 7, 1}, {1, 2, 1}, {1, 7, 1}, 
            {2, 3, 0}, {2, 5, 0}, {2, 8, 1}, {3, 4, 1}, {3, 5, 1},
            {4, 5, 1}, {5, 6, 1}, {6, 7, 1}, {7, 8, 1}
        };
        
        int[] res = minDist(n, src, edges);
        for (int i = 0; i < n; i++) {
            System.out.print(res[i] + " ");
        }
        System.out.println();
    }
}
Python
# Python program to implement 0-1 BFS 
# (Shortest Path in a Binary Weight Graph)
from collections import deque

def minDist(n, src, edges):
    
    # Create adjacency list representation of the graph
    adj = [[] for _ in range(n)]
    for edge in edges:
        u = edge[0]
        v = edge[1]
        w = edge[2]
        adj[u].append((v, w))
        adj[v].append((u, w))
    
    # Initialize distances to infinity
    dist = [float('inf')] * n
    dist[src] = 0
    
    # Use deque for 0-1 BFS
    dq = deque()
    dq.append(src)
    
    while dq:
        u = dq.popleft()
        
        # Process all adjacent vertices
        for edge in adj[u]:
            v = edge[0]
            weight = edge[1]
            
            # If we can improve the distance
            if dist[u] + weight < dist[v]:
                dist[v] = dist[u] + weight
                
                # If weight is 0, push to front (higher priority)
                # If weight is 1, push to back (lower priority)
                if weight == 0:
                    dq.appendleft(v)
                else:
                    dq.append(v)
    
    return dist

if __name__ == "__main__":
    n = 9
    src = 0
    edges = [
        [0, 1, 0], [0, 7, 1], [1, 2, 1], [1, 7, 1], 
        [2, 3, 0], [2, 5, 0], [2, 8, 1], [3, 4, 1], [3, 5, 1],
        [4, 5, 1], [5, 6, 1], [6, 7, 1], [7, 8, 1]
    ]
    
    res = minDist(n, src, edges)
    for val in res:
        print(val, end=" ")
    print()
C#
// C# program to implement 0-1 BFS 
// (Shortest Path in a Binary Weight Graph)
using System;
using System.Collections.Generic;

class GfG {
    static int[] MinDist(int n, int src, int[][] edges) {
        
        // Create adjacency list representation of the graph
        List<Tuple<int, int>>[] adj = new List<Tuple<int, int>>[n];
        for (int i = 0; i < n; i++) {
            adj[i] = new List<Tuple<int, int>>();
        }
        
        foreach (var edge in edges) {
            int u = edge[0];
            int v = edge[1];
            int w = edge[2];
            adj[u].Add(Tuple.Create(v, w));
            adj[v].Add(Tuple.Create(u, w));
        }
        
        // Initialize distances to infinity
        int[] dist = new int[n];
        for (int i = 0; i < n; i++) {
            dist[i] = int.MaxValue;
        }
        dist[src] = 0;
        
        // Use deque for 0-1 BFS
        LinkedList<int> dq = new LinkedList<int>();
        dq.AddLast(src);
        
        while (dq.Count > 0) {
            int u = dq.First.Value;
            dq.RemoveFirst();
            
            // Process all adjacent vertices
            foreach (var edge in adj[u]) {
                int v = edge.Item1;
                int weight = edge.Item2;
                
                // If we can improve the distance
                if (dist[u] + weight < dist[v]) {
                    dist[v] = dist[u] + weight;
                    
                    // If weight is 0, push to front (higher priority)
                    // If weight is 1, push to back (lower priority)
                    if (weight == 0)
                        dq.AddFirst(v);
                    else
                        dq.AddLast(v);
                }
            }
        }
        
        return dist;
    }

    static void Main() {
        int n = 9, src = 0;
        int[][] edges = new int[][] {
            new int[] {0, 1, 0}, new int[] {0, 7, 1}, 
            new int[] {1, 2, 1}, new int[] {1, 7, 1}, 
            new int[] {2, 3, 0}, new int[] {2, 5, 0}, 
            new int[] {2, 8, 1}, new int[] {3, 4, 1}, 
            new int[] {3, 5, 1}, new int[] {4, 5, 1}, 
            new int[] {5, 6, 1}, new int[] {6, 7, 1}, 
            new int[] {7, 8, 1}
        };
        
        int[] res = MinDist(n, src, edges);
        foreach (int val in res) {
            Console.Write(val + " ");
        }
        Console.WriteLine();
    }
}
JavaScript
// JavaScript program to implement 0-1 BFS 
// (Shortest Path in a Binary Weight Graph)
function minDist(n, src, edges) {
    
    // Create adjacency list representation of the graph
    let adj = Array.from({length: n}, () => []);
    for (let edge of edges) {
        let u = edge[0];
        let v = edge[1];
        let w = edge[2];
        adj[u].push([v, w]);
        adj[v].push([u, w]);
    }
    
    // Initialize distances to infinity
    let dist = new Array(n).fill(Infinity);
    dist[src] = 0;
    
    // Use deque for 0-1 BFS
    let dq = [];
    dq.push(src);
    
    while (dq.length > 0) {
        let u = dq.shift();
        
        // Process all adjacent vertices
        for (let edge of adj[u]) {
            let v = edge[0];
            let weight = edge[1];
            
            // If we can improve the distance
            if (dist[u] + weight < dist[v]) {
                dist[v] = dist[u] + weight;
                
                // If weight is 0, push to front (higher priority)
                // If weight is 1, push to back (lower priority)
                if (weight === 0)
                    dq.unshift(v);
                else
                    dq.push(v);
            }
        }
    }
    
    return dist;
}

let n = 9, src = 0;
let edges = [
    [0, 1, 0], [0, 7, 1], [1, 2, 1], [1, 7, 1], 
    [2, 3, 0], [2, 5, 0], [2, 8, 1], [3, 4, 1], [3, 5, 1],
    [4, 5, 1], [5, 6, 1], [6, 7, 1], [7, 8, 1]
];

let res = minDist(n, src, edges);
console.log(res.join(' '));

Output
0 0 1 1 2 1 2 1 2 

Next Article
Article Tags :
Practice Tags :

Similar Reads