Skip to content
Related Articles
Get the best out of our app
GFG App
Open App
geeksforgeeks
Browser
Continue

Related Articles

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

Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article

Given a graph where every edge has weight as either 0 or 1. A source vertex is also given in the graph. Find the shortest path from the source vertex to every other vertex. 

For Example: 

Input : Source Vertex = 0 and below graph 

Output : Shortest distances from given source
         0 0 1 1 2 1 2 1 2

Explanation : 
Shortest distance from 0 to 0 is 0
Shortest distance from 0 to 1 is 0
Shortest distance from 0 to 2 is 1
..................

In normal BFS of a graph, all edges have equal weight but in 0-1 BFS some edges may have 0 weight and some may have 1 weight. In this, we will not use a bool array to mark visited nodes but at each step, we will check for the optimal distance condition. We use a double-ended queue to store the node. While performing BFS if an edge having weight = 0 is found node is pushed at front of the double-ended queue and if an edge having weight = 1 is found, it is pushed to the back of the double-ended queue.
The approach is similar to Dijkstra that if the shortest distance to the node is relaxed by the previous node then only it will be pushed into the queue. 
The above idea works in all cases, when pop a vertex (like Dijkstra), it is the minimum weight vertex among the remaining vertices. If there is a 0-weight vertex adjacent to it, then this adjacent has the same distance. If there is a 1 weight adjacent, then this adjacent has maximum distance among all vertices in the dequeue (because all other vertices are either adjacent to the currently popped vertex or adjacent to previously popped vertices).
Below is the implementation of the above idea. 
 

C++




// C++ program to implement single source
// shortest path for a Binary Graph
#include<bits/stdc++.h>
using namespace std;
 
/* no.of vertices */
#define V 9
 
// a structure to represent edges
struct node
{
    // two variable one denote the node
    // and other the weight
    int to, weight;
};
 
// vector to store edges
vector <node> edges[V];
 
// Prints shortest distance from given source to
// every other vertex
void zeroOneBFS(int src)
{
    // Initialize distances from given source
    int dist[V];
    for (int i=0; i<V; i++)
        dist[i] = INT_MAX;
 
    // double ende queue to do BFS.
    deque <int> Q;
    dist[src] = 0;
    Q.push_back(src);
 
    while (!Q.empty())
    {
        int v = Q.front();
        Q.pop_front();
 
        for (int i=0; i<edges[v].size(); i++)
        {
            // checking for the optimal distance
            if (dist[edges[v][i].to] > dist[v] + edges[v][i].weight)
            {
                dist[edges[v][i].to] = dist[v] + edges[v][i].weight;
 
                // Put 0 weight edges to front and 1 weight
                // edges to back so that vertices are processed
                // in increasing order of weights.
                if (edges[v][i].weight == 0)
                    Q.push_front(edges[v][i].to);
                else
                    Q.push_back(edges[v][i].to);
            }
        }
    }
 
    // printing the shortest distances
    for (int i=0; i<V; i++)
        cout << dist[i] << " ";
}
 
void addEdge(int u, int v, int wt)
{
   edges[u].push_back({v, wt});
   edges[v].push_back({u, wt});
}
 
// Driver function
int main()
{
    addEdge(0, 1, 0);
    addEdge(0, 7, 1);
    addEdge(1, 7, 1);
    addEdge(1, 2, 1);
    addEdge(2, 3, 0);
    addEdge(2, 5, 0);
    addEdge(2, 8, 1);
    addEdge(3, 4, 1);
    addEdge(3, 5, 1);
    addEdge(4, 5, 1);
    addEdge(5, 6, 1);
    addEdge(6, 7, 1);
    addEdge(7, 8, 1);
    int src = 0;//source node
    zeroOneBFS(src);
    return 0;
}


Java




// Java Program to implement 0-1 BFS
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
 
public class ZeroOneBFS {
    private static class Node {
        int to; // the ending vertex
        int weight; // the weight of the edge
         
        public Node(int to, int wt) {
            this.to = to;
            this.weight = wt;
        }
    }
     
    private static final int numVertex = 9;
    private ArrayList<Node>[] edges = new ArrayList[numVertex];
     
    public ZeroOneBFS() {
        for (int i = 0; i < edges.length; i++) {
            edges[i] = new ArrayList<Node>();
        }
    }
     
    public void addEdge(int u, int v, int wt) {
        edges[u].add(edges[u].size(), new Node(v, wt));
        edges[v].add(edges[v].size(), new Node(u, wt));
    }
     
    public void zeroOneBFS(int src) {
 
        // initialize distances from given source
        int[] dist = new int[numVertex];
        for (int i = 0; i < numVertex; i++) {
            dist[i] = Integer.MAX_VALUE;
        }
         
        // double ended queue to do BFS
        Deque<Integer> queue = new ArrayDeque<Integer>();
        dist[src] = 0;
        queue.addLast(src);
         
        while (!queue.isEmpty()) {
            int v = queue.removeFirst();
            for (int i = 0; i < edges[v].size(); i++) {
 
                // checking for optimal distance
                if (dist[edges[v].get(i).to] >
                        dist[v] + edges[v].get(i).weight) {
 
                    // update the distance
                    dist[edges[v].get(i).to] =
                          dist[v] + edges[v].get(i).weight;
 
                    // put 0 weight edges to front and 1
                    // weight edges to back so that vertices
                    // are processed in increasing order of weight
                    if (edges[v].get(i).weight == 0) {
                        queue.addFirst(edges[v].get(i).to);
                    } else {
                        queue.addLast(edges[v].get(i).to);
                    }
                }
            }
        }
         
        for (int i = 0; i < dist.length; i++) {
            System.out.print(dist[i] + " ");
        }
    }
     
    public static void main(String[] args) {
        ZeroOneBFS graph = new ZeroOneBFS();
        graph.addEdge(0, 1, 0);
        graph.addEdge(0, 7, 1);
        graph.addEdge(1, 7, 1);
        graph.addEdge(1, 2, 1);
        graph.addEdge(2, 3, 0);
        graph.addEdge(2, 5, 0);
        graph.addEdge(2, 8, 1);
        graph.addEdge(3, 4, 1);
        graph.addEdge(3, 5, 1);
        graph.addEdge(4, 5, 1);
        graph.addEdge(5, 6, 1);
        graph.addEdge(6, 7, 1);
        graph.addEdge(7, 8, 1);
        int src = 0;//source node
        graph.zeroOneBFS(src);
        return;
    }
}


Python3




# Python3 program to implement single source
# shortest path for a Binary Graph
from sys import maxsize as INT_MAX
from collections import deque
 
# no.of vertices
V = 9
 
# a structure to represent edges
class node:
    def __init__(self, to, weight):
 
        # two variable one denote the node
        # and other the weight
        self.to = to
        self.weight = weight
 
# vector to store edges
edges = [0] * V
for i in range(V):
    edges[i] = []
 
# Prints shortest distance from
# given source to every other vertex
def zeroOneBFS(src: int):
 
    # Initialize distances from given source
    dist = [0] * V
    for i in range(V):
        dist[i] = INT_MAX
 
    # double ende queue to do BFS.
    Q = deque()
    dist[src] = 0
    Q.append(src)
 
    while Q:
        v = Q[0]
        Q.popleft()
 
        for i in range(len(edges[v])):
 
            # checking for the optimal distance
            if (dist[edges[v][i].to] >
                dist[v] + edges[v][i].weight):
                dist[edges[v][i].to] = dist[v] + edges[v][i].weight
 
                # Put 0 weight edges to front and 1 weight
                # edges to back so that vertices are processed
                # in increasing order of weights.
                if edges[v][i].weight == 0:
                    Q.appendleft(edges[v][i].to)
                else:
                    Q.append(edges[v][i].to)
 
    # printing the shortest distances
    for i in range(V):
        print(dist[i], end = " ")
    print()
 
def addEdge(u: int, v: int, wt: int):
    edges[u].append(node(v, wt))
    edges[u].append(node(v, wt))
 
# Driver Code
if __name__ == "__main__":
 
    addEdge(0, 1, 0)
    addEdge(0, 7, 1)
    addEdge(1, 7, 1)
    addEdge(1, 2, 1)
    addEdge(2, 3, 0)
    addEdge(2, 5, 0)
    addEdge(2, 8, 1)
    addEdge(3, 4, 1)
    addEdge(3, 5, 1)
    addEdge(4, 5, 1)
    addEdge(5, 6, 1)
    addEdge(6, 7, 1)
    addEdge(7, 8, 1)
 
    # source node
    src = 0
    zeroOneBFS(src)
 
# This code is contributed by
# sanjeev2552


C#




// C# Program to implement 0-1 BFS
using System;
using System.Collections.Generic;
 
class ZeroOneBFS {
    private class Node {
        public int to; // the ending vertex
        public int weight; // the weight of the edge
         
        public Node(int to, int wt) {
            this.to = to;
            this.weight = wt;
        }
    }
     
    private const int numVertex = 9;
    private List<Node>[] edges = new List<Node>[numVertex];
     
    public ZeroOneBFS() {
        for (int i = 0; i < edges.Length; i++) {
            edges[i] = new List<Node>();
        }
    }
     
    public void addEdge(int u, int v, int wt) {
        edges[u].Add(new Node(v, wt));
        edges[v].Add(new Node(u, wt));
    }
     
    public void zeroOneBFS(int src) {
        // initialize distances from given source
        int[] dist = new int[numVertex];
        for (int i = 0; i < numVertex; i++) {
            dist[i] = int.MaxValue;
        }
         
        // double ended queue to do BFS
        Queue<int> queue = new Queue<int>();
        dist[src] = 0;
        queue.Enqueue(src);
         
        while (queue.Count > 0) {
            int v = queue.Dequeue();
            for (int i = 0; i < edges[v].Count; i++) {
                // checking for optimal distance
                if (dist[edges[v][i].to] >
                        dist[v] + edges[v][i].weight) {
 
                    // update the distance
                    dist[edges[v][i].to] =
                          dist[v] + edges[v][i].weight;
 
                    // put 0 weight edges to front and 1
                    // weight edges to back so that vertices
                    // are processed in increasing order of weight
                    if (edges[v][i].weight == 0) {
                        queue.Enqueue(edges[v][i].to);
                    } else {
                        queue.Enqueue(edges[v][i].to);
                    }
                }
            }
        }
         
        for (int i = 0; i < dist.Length; i++) {
            Console.Write(dist[i] + " ");
        }
    }
     
    static void Main(string[] args) {
        ZeroOneBFS graph = new ZeroOneBFS();
        graph.addEdge(0, 1, 0);
        graph.addEdge(0, 7, 1);
        graph.addEdge(1, 7, 1);
        graph.addEdge(1, 2, 1);
        graph.addEdge(2, 3, 0);
        graph.addEdge(2, 5, 0);
        graph.addEdge(2, 8, 1);
        graph.addEdge(3, 4, 1);
        graph.addEdge(3, 5, 1);
        graph.addEdge(4, 5, 1);
        graph.addEdge(5, 6, 1);
        graph.addEdge(6, 7, 1);
        graph.addEdge(7, 8, 1);
        int src = 0;//source node
        graph.zeroOneBFS(src);
        return;
    }
}
// This code is contributed by Prajwal Kandekar


Javascript




<script>
// Javascript Program to implement 0-1 BFS
 
class Node
{
    constructor(to,wt)
    {
        this.to = to;
            this.weight = wt;
    }
     
}
 
let numVertex = 9;
let edges = new Array(numVertex);
 
function _ZeroOneBFS()
{
    for (let i = 0; i < edges.length; i++) {
            edges[i] = [];
        }
}
 
function addEdge(u,v,wt)
{
    edges[u].push(edges[u].length, new Node(v, wt));
        edges[v].push(edges[v].length, new Node(u, wt));
}
 
function zeroOneBFS(src)
{
    // initialize distances from given source
        let dist = new Array(numVertex);
        for (let i = 0; i < numVertex; i++) {
            dist[i] = Number.MAX_VALUE;
        }
           
        // double ended queue to do BFS
        let queue = [];
        dist[src] = 0;
        queue.push(src);
           
        while (queue.length!=0) {
            let v = queue.shift();
            for (let i = 0; i < edges[v].length; i++) {
   
                // checking for optimal distance
                if (dist[edges[v][i].to] >
                        dist[v] + edges[v][i].weight) {
   
                    // update the distance
                    dist[edges[v][i].to] =
                          dist[v] + edges[v][i].weight;
   
                    // put 0 weight edges to front and 1
                    // weight edges to back so that vertices
                    // are processed in increasing order of weight
                    if (edges[v][i].weight == 0) {
                        queue.unshift(edges[v][i].to);
                    } else {
                        queue.push(edges[v][i].to);
                    }
                }
            }
        }
           
        for (let i = 0; i < dist.length; i++) {
            document.write(dist[i] + " ");
        }
}
 
_ZeroOneBFS();
addEdge(0, 1, 0);
addEdge(0, 7, 1);
addEdge(1, 7, 1);
addEdge(1, 2, 1);
addEdge(2, 3, 0);
addEdge(2, 5, 0);
addEdge(2, 8, 1);
addEdge(3, 4, 1);
addEdge(3, 5, 1);
addEdge(4, 5, 1);
addEdge(5, 6, 1);
addEdge(6, 7, 1);
addEdge(7, 8, 1);
let src = 0;//source node
zeroOneBFS(src);
 
// This code is contributed by avanitrachhadiya2155
</script>


Output

0 0 1 1 2 1 2 1 2 

This problem can also be solved by Dijkstra but the time complexity will be O(E + V Log V) whereas by BFS it will be O(V+E).
 
This article is contributed by Ayush Jha. If you like GeeksforGeeks and would like to contribute, you can write an article using write.geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks. Please write comments if you find anything incorrect, or if you want to share more information about the topic discussed above.


My Personal Notes arrow_drop_up
Like Article
Save Article
Similar Reads
Related Tutorials