Home About My Portfolio Privacy Policy Terms

Friday, 10 February 2023

Multi Source BFS

In normal BFS, there is a single starting node (or source) which is pushed inside the queue from where we start traversing other nodes until the queue is not empty. Whereas in multi source BFS, we have multiple starting nodes, all of which are initially pushed into the queue and then traversal is started.

Let us consider an example of normal BFS

Given above graph, we have to find the distance between source node 1 and destination node 4.
Here's the simple BFS solution that works in O(n) time.

    #include<bits/stdc++.h>
    using namespace std;

    int distBetween(vector<int>*adj,int n,int src,int dest){
        queue<pair<int,int>>q;
        int d=0;
        q.push({src,d});
        vector<int>vis(n+1);

        while(!q.empty()){
            src=q.front().first;
            d=q.front().second;
            q.pop();
            if(vis[src])continue;
            vis[src]=1;
            if(src==dest)return d;
            for(auto &v:adj[src])
                q.push({v,d+1});
        }
        return -1;
    }

    int main(){
        system("CLS");

        int n=6;
        vector<int>adj[n+1];
        adj[1]={3,5};
        adj[2]={3,6};
        adj[3]={1,2,4,5,6};
        adj[4]={3,6};
        adj[5]={1,3,6};
        adj[6]={2,3,4,5};

        int src=1, dest=6;
        cout<<distBetween(adj,n,src,dest);

        return 0;
    };



Now, let consider a new problem. Among the nodes 1, 3 and 5, what is the closest distance from node 2?
Naive solution to this problem is to use a BFS for each given source nodes and find distance of them from destination node and return the minimum distance.

Time complexity will be O(number of nodes * BFS time for each node)
In worst case, number of nodes can be n (where n is the number of nodes in the graph), in this case time complexity will be O(n*n).


    #include<bits/stdc++.h>
    using namespace std;

    int distBetween(vector<int>*adj,int n,int src,int dest){
        queue<pair<int,int>>q;
        int d=0;
        q.push({src,d});
        vector<int>vis(n+1);

        while(!q.empty()){
            src=q.front().first;
            d=q.front().second;
            q.pop();
            if(vis[src])continue;
            vis[src]=1;
            if(src==dest)
                return d;
            for(auto &v:adj[src])
                q.push({v,d+1});
        }
        return -1;
    }

    int main(){
        system("CLS");

        int n=6;
        vector<int>adj[n+1];
        adj[1]={3,5};
        adj[2]={3,6};
        adj[3]={1,2,4,5,6};
        adj[4]={3,6};
        adj[5]={1,3,6};
        adj[6]={2,3,4,5};

        int src1=1,src2=3,src3=5, dest=6;
        cout<<min({distBetween(adj,n,src1,dest),
                   distBetween(adj,n,src2,dest),
                   distBetween(adj,n,src3,dest)});
        return 0;
    };



Efficient solution: Using multi source BFS.
It is similar to normal BFS, but unlike normal BFS, we push all the source nodes to the queue before starting the traversal.

Time complexity: O(n)


    #include<bits/stdc++.h>
    using namespace std;

    int distBetween(vector<int>*adj,int n,vector<int>&src,int dest){
       
        queue<pair<int,int>>q;
        int d=0;

        for(auto &s:src)
            q.push({s,d});

        vector<int>vis(n+1);
        while(!q.empty()){
            int s=q.front().first;
            d=q.front().second;
            q.pop();
            if(vis[s])continue;
            vis[s]=1;
            if(s==dest)
                return d;
            for(auto &v:adj[s])
                q.push({v,d+1});
        }
        return -1;
    }

    int main(){
        system("CLS");

        int n=6;
        vector<int>adj[n+1];
        adj[1]={3,5};
        adj[2]={3,6};
        adj[3]={1,2,4,5,6};
        adj[4]={3,6};
        adj[5]={1,3,6};
        adj[6]={2,3,4,5};

        int dest=6;
        vector<int>src={1,2,3};
        cout<<distBetween(adj,n,src,dest);
        return 0;
    };





Related problems