Multi Source Shortest Path in Unweighted Graph
Suppose there are n towns connected by m bidirectional roads. There are s towns among them with a police station. We want to find out the distance of each town from the nearest police station. If the town itself has one the distance is 0.
Example:
Input : Number of Vertices = 6 Number of Edges = 9 Towns with Police Station : 1, 5 Edges: 1 2 1 6 2 6 2 3 3 6 5 4 6 5 3 4 5 3
Output : 1 0 2 1 3 1 4 1 5 0 6 1
Naive Approach: We can loop through the vertices and from each vertex run a BFS to find the closest town with police station from that vertex. This will take O(V.E).
Naive approach implementation using BFS from each vertex:
C++
// C++ program to demonstrate distance to // nearest source problem using BFS // from each vertex #include <bits/stdc++.h> using namespace std; #define N 100000 + 1 #define inf 1000000 // This array stores the distances of the // vertices from the nearest source int dist[N]; // a hash array where source[i] = 1 // means vertex i is a source int source[N]; // The BFS Queue // The pairs are of the form (vertex, distance // from current source) deque<pair< int , int > > BFSQueue; // visited array for remembering visited vertices int visited[N]; // The BFS function void BFS(vector< int > graph[], int start) { // clearing the queue while (!BFSQueue.empty()) BFSQueue.pop_back(); // push_back starting vertices BFSQueue.push_back({ start, 0 }); while (!BFSQueue.empty()) { int s = BFSQueue.front().first; int d = BFSQueue.front().second; visited[s] = 1; BFSQueue.pop_front(); // stop at the first source we reach during BFS if (source[s] == 1) { dist[start] = d; return ; } // Pushing the adjacent unvisited vertices // with distance from current source = this // vertex's distance + 1 for ( int i = 0; i < graph[s].size(); i++) if (visited[graph[s][i]] == 0) BFSQueue.push_back({ graph[s][i], d + 1 }); } } // This function calculates the distance of each // vertex from nearest source void nearestTown(vector< int > graph[], int n, int sources[], int S) { // resetting the source hash array for ( int i = 1; i <= n; i++) source[i] = 0; for ( int i = 0; i <= S - 1; i++) source[sources[i]] = 1; // loop through all the vertices and run // a BFS from each vertex to find the distance // to nearest town from it for ( int i = 1; i <= n; i++) { for ( int i = 1; i <= n; i++) visited[i] = 0; BFS(graph, i); } // Printing the distances for ( int i = 1; i <= n; i++) cout << i << " " << dist[i] << endl; } void addEdge(vector< int > graph[], int u, int v) { graph[u].push_back(v); graph[v].push_back(u); } // Driver Code int main() { // Number of vertices int n = 6; vector< int > graph[n + 1]; // Edges addEdge(graph, 1, 2); addEdge(graph, 1, 6); addEdge(graph, 2, 6); addEdge(graph, 2, 3); addEdge(graph, 3, 6); addEdge(graph, 5, 4); addEdge(graph, 6, 5); addEdge(graph, 3, 4); addEdge(graph, 5, 3); // Sources int sources[] = { 1, 5 }; int S = sizeof (sources) / sizeof (sources[0]); nearestTown(graph, n, sources, S); return 0; } |
Java
// Java program to demonstrate distance to // nearest source problem using BFS // from each vertex import java.util.ArrayList; import java.util.Arrays; import java.util.Deque; import java.util.LinkedList; class Pair { int first, second; public Pair( int first, int second) { this .first = first; this .second = second; } } class GFG{ static final int N = 100000 + 1 ; static final int inf = 1000000 ; // This array stores the distances of the // vertices from the nearest source static int [] dist = new int [N]; // a hash array where source[i] = 1 // means vertex i is a source static int [] source = new int [N]; // The BFS Queue // The pairs are of the form (vertex, distance // from current source) static Deque<Pair> BFSQueue = new LinkedList<>(); // deque<pair<int, int> > BFSQueue; // visited array for remembering visited vertices static int [] visited = new int [N]; // The BFS function static void BFS(ArrayList<Integer>[] graph, int start) { // Clearing the queue while (!BFSQueue.isEmpty()) BFSQueue.removeLast(); // push_back starting vertices BFSQueue.add( new Pair(start, 0 )); while (!BFSQueue.isEmpty()) { int s = BFSQueue.peekFirst().first; int d = BFSQueue.peekFirst().second; visited[s] = 1 ; BFSQueue.removeFirst(); // Stop at the first source // we reach during BFS if (source[s] == 1 ) { dist[start] = d; return ; } // Pushing the adjacent unvisited vertices // with distance from current source = this // vertex's distance + 1 for ( int i = 0 ; i < graph[s].size(); i++) if (visited[graph[s].get(i)] == 0 ) BFSQueue.add( new Pair( graph[s].get(i), d + 1 )); } } // This function calculates the distance of each // vertex from nearest source static void nearestTown(ArrayList<Integer>[] graph, int n, int sources[], int S) { // Resetting the source hash array for ( int i = 1 ; i <= n; i++) source[i] = 0 ; for ( int i = 0 ; i <= S - 1 ; i++) source[sources[i]] = 1 ; // Loop through all the vertices and run // a BFS from each vertex to find the distance // to nearest town from it for ( int i = 1 ; i <= n; i++) { for ( int j = 1 ; j <= n; j++) visited[j] = 0 ; BFS(graph, i); } // Printing the distances for ( int i = 1 ; i <= n; i++) System.out.println(i + " " + dist[i]); } static void addEdge(ArrayList<Integer>[] graph, int u, int v) { graph[u].add(v); graph[v].add(u); } // Driver Code public static void main(String[] args) { // Number of vertices int n = 6 ; @SuppressWarnings ( "unchecked" ) ArrayList<Integer>[] graph = new ArrayList[n + 1 ]; Arrays.fill(graph, new ArrayList<>()); // Edges addEdge(graph, 1 , 2 ); addEdge(graph, 1 , 6 ); addEdge(graph, 2 , 6 ); addEdge(graph, 2 , 3 ); addEdge(graph, 3 , 6 ); addEdge(graph, 5 , 4 ); addEdge(graph, 6 , 5 ); addEdge(graph, 3 , 4 ); addEdge(graph, 5 , 3 ); // Sources int sources[] = { 1 , 5 }; int S = sources.length; nearestTown(graph, n, sources, S); } } // This code is contributed by sanjeev2552 |
Python3
# Python3 program to demonstrate distance to # nearest source problem using BFS # from each vertex N = 100001 inf = 1000000 # This array stores the distances of the # vertices from the nearest source dist = [ 0 for i in range (N)]; # a hash array where source[i] = 1 # means vertex i is a source source = [ 0 for i in range (N)]; # The BFS Queue # The pairs are of the form (vertex, distance # from current source) BFSQueue = [] # visited array for remembering visited vertices visited = [ 0 for i in range (N)]; # The BFS function def BFS(graph, start): # clearing the queue while ( len (BFSQueue) ! = 0 ): BFSQueue.pop(); # append starting vertices BFSQueue.append([ start, 0 ]); while ( len (BFSQueue) ! = 0 ): s = BFSQueue[ 0 ][ 0 ]; d = BFSQueue[ 0 ][ 1 ]; visited[s] = 1 ; BFSQueue.pop( 0 ); # stop at the first source we reach during BFS if (source[s] = = 1 ): dist[start] = d; return ; # Pushing the adjacent unvisited vertices # with distance from current source = this # vertex's distance + 1 for i in range ( len (graph[s])): if (visited[graph[s][i]] = = 0 ): BFSQueue.append([ graph[s][i], d + 1 ]); # This function calculates the distance of each # vertex from nearest source def nearestTown(graph, n, sources, S): global source, dist # resetting the source hash array for i in range ( 1 , n + 1 ): source[i] = 0 ; for i in range (S): source[sources[i]] = 1 ; # loop through all the vertices and run # a BFS from each vertex to find the distance # to nearest town from it for i in range ( 1 , n + 1 ): for j in range ( 1 , n + 1 ): visited[j] = 0 ; BFS(graph, i); # Printing the distances for i in range ( 1 , n + 1 ): print ( '{} {}' . format (i,dist[i])) def addEdge(graph, u, v): graph[u].append(v); graph[v].append(u); # Driver Code if __name__ = = '__main__' : # Number of vertices n = 6 graph = [[] for i in range (n + 1 )]; # Edges addEdge(graph, 1 , 2 ); addEdge(graph, 1 , 6 ); addEdge(graph, 2 , 6 ); addEdge(graph, 2 , 3 ); addEdge(graph, 3 , 6 ); addEdge(graph, 5 , 4 ); addEdge(graph, 6 , 5 ); addEdge(graph, 3 , 4 ); addEdge(graph, 5 , 3 ); # Sources sources = [ 1 , 5 ] S = len (sources) nearestTown(graph, n, sources, S); # This code is contributed by rutvik_56 |
C#
// C# program to demonstrate distance to // nearest source problem using BFS // from each vertex using System; using System.Collections.Generic; class GFG { static int N = 100000 + 1; // This array stores the distances of the // vertices from the nearest source static int [] dist = new int [N]; // a hash array where source[i] = 1 // means vertex i is a source static int [] source = new int [N]; // The BFS Queue // The pairs are of the form (vertex, distance // from current source) static List<Tuple< int , int >> BFSQueue = new List<Tuple< int , int >>(); // deque<pair<int, int> > BFSQueue; // visited array for remembering visited vertices static int [] visited = new int [N]; // The BFS function static void BFS(List<List< int >> graph, int start) { // Clearing the queue while (BFSQueue.Count > 0) BFSQueue.RemoveAt(BFSQueue.Count - 1); // push_back starting vertices BFSQueue.Add( new Tuple< int , int >(start, 0)); while (BFSQueue.Count > 0) { int s = BFSQueue[0].Item1; int d = BFSQueue[0].Item2; visited[s] = 1; BFSQueue.RemoveAt(0); // Stop at the first source // we reach during BFS if (source[s] == 1) { dist[start] = d; return ; } // Pushing the adjacent unvisited vertices // with distance from current source = this // vertex's distance + 1 for ( int i = 0; i < graph[s].Count; i++) if (visited[graph[s][i]] == 0) BFSQueue.Add( new Tuple< int , int >( graph[s][i], d + 1)); } } // This function calculates the distance of each // vertex from nearest source static void nearestTown(List<List< int >> graph, int n, int [] sources, int S) { // Resetting the source hash array for ( int i = 1; i <= n; i++) source[i] = 0; for ( int i = 0; i <= S - 1; i++) source[sources[i]] = 1; // Loop through all the vertices and run // a BFS from each vertex to find the distance // to nearest town from it for ( int i = 1; i <= n; i++) { for ( int j = 1; j <= n; j++) visited[j] = 0; BFS(graph, i); } // Printing the distances for ( int i = 1; i <= n; i++) Console.WriteLine(i + " " + dist[i]); } static void addEdge(List<List< int >> graph, int u, int v) { graph[u].Add(v); graph[v].Add(u); } static void Main() { // Number of vertices int n = 6; List<List< int >> graph = new List<List< int >>(); for ( int i = 0; i < n + 1; i++) { graph.Add( new List< int >()); } // Edges addEdge(graph, 1, 2); addEdge(graph, 1, 6); addEdge(graph, 2, 6); addEdge(graph, 2, 3); addEdge(graph, 3, 6); addEdge(graph, 5, 4); addEdge(graph, 6, 5); addEdge(graph, 3, 4); addEdge(graph, 5, 3); // Sources int [] sources = { 1, 5 }; int S = sources.Length; nearestTown(graph, n, sources, S); } } // This code is contributed by divyeshrabadiya07. |
Javascript
<script> // Javascript program to demonstrate distance to // nearest source problem using BFS // from each vertex let N = 100000 + 1; // This array stores the distances of the // vertices from the nearest source let dist = new Array(N); // a hash array where source[i] = 1 // means vertex i is a source let source = new Array(N); // The BFS Queue // The pairs are of the form (vertex, distance // from current source) let BFSQueue = []; // deque<pair<int, int> > BFSQueue; // visited array for remembering visited vertices let visited = new Array(N); // The BFS function function BFS(graph, start) { // Clearing the queue while (BFSQueue.length > 0) BFSQueue.pop(); // push_back starting vertices BFSQueue.push([start, 0]); while (BFSQueue.length > 0) { let s = BFSQueue[0][0]; let d = BFSQueue[0][1]; visited[s] = 1; BFSQueue.shift(); // Stop at the first source // we reach during BFS if (source[s] == 1) { dist[start] = d; return ; } // Pushing the adjacent unvisited vertices // with distance from current source = this // vertex's distance + 1 for (let i = 0; i < graph[s].length; i++) if (visited[graph[s][i]] == 0) BFSQueue.push([graph[s][i], d + 1]); } } // This function calculates the distance of each // vertex from nearest source function nearestTown(graph, n, sources, S) { // Resetting the source hash array for (let i = 1; i <= n; i++) source[i] = 0; for (let i = 0; i <= S - 1; i++) source[sources[i]] = 1; // Loop through all the vertices and run // a BFS from each vertex to find the distance // to nearest town from it for (let i = 1; i <= n; i++) { for (let j = 1; j <= n; j++) visited[j] = 0; BFS(graph, i); } // Printing the distances for (let i = 1; i <= n; i++) document.write(i + " " + dist[i] + "</br>" ); } function addEdge(graph, u, v) { graph[u].push(v); graph[v].push(u); } // Number of vertices let n = 6; let graph = []; for (let i = 0; i < n + 1; i++) { graph.push([]); } // Edges addEdge(graph, 1, 2); addEdge(graph, 1, 6); addEdge(graph, 2, 6); addEdge(graph, 2, 3); addEdge(graph, 3, 6); addEdge(graph, 5, 4); addEdge(graph, 6, 5); addEdge(graph, 3, 4); addEdge(graph, 5, 3); // Sources let sources = [ 1, 5 ]; let S = sources.length; nearestTown(graph, n, sources, S); // This code is contributed by mukesh07. </script> |
1 0 2 1 3 1 4 1 5 0 6 1
Complexity Analysis:
- Time Complexity: O(V.E)
- Auxiliary Space: O(V)
Efficient Method A better method is to use the Dijkstra’s algorithm in a modified way. Let’s consider one of the sources as the original source and the other sources to be vertices with 0 cost paths from the original source. Thus we push all the sources into the Dijkstra Queue with distance = 0, and the rest of the vertices with distance = infinity. The minimum distance of each vertex from the original source now calculated using the Dijkstra’s Algorithm are now essentially the distances from the nearest source.
Explanation:
The C++ implementation uses a set of pairs (distance from the source, vertex) sorted according to the distance from the source. Initially, the set contains the sources with distance = 0 and all the other vertices with distance = infinity.
On each step, we will go to the vertex with minimum distance(d) from source, i.e, the first element of the set (the source itself in the first step with distance = 0). We go through all it’s adjacent vertices and if the distance of any vertex is > d + 1 we replace its entry in the set with the new distance. Then we remove the current vertex from the set. We continue this until the set is empty.
The idea is there cannot be a shorter path to the vertex at the front of the set than the current one since any other path will be a sum of a longer path (>= it’s length) and a non-negative path length (unless we are considering negative edges).
Since all the sources have a distance = 0, in the beginning, the adjacent non-source vertices will get a distance = 1. All vertices will get distance = distance from their nearest source.
Implementation of Efficient Approach:
C++
// C++ program to demonstrate // multi-source BFS #include <bits/stdc++.h> using namespace std; #define N 100000 + 1 #define inf 1000000 // This array stores the distances of the vertices // from the nearest source int dist[N]; // This Set contains the vertices not yet visited in // increasing order of distance from the nearest source // calculated till now set<pair< int , int > > Q; // Util function for Multi-Source BFS void multiSourceBFSUtil(vector< int > graph[], int s) { set<pair< int , int > >::iterator it; int i; for (i = 0; i < graph[s].size(); i++) { int v = graph[s][i]; if (dist[s] + 1 < dist[v]) { // If a shorter path to a vertex is // found than the currently stored // distance replace it in the Q it = Q.find({ dist[v], v }); Q.erase(it); dist[v] = dist[s] + 1; Q.insert({ dist[v], v }); } } // Stop when the Q is empty -> All // vertices have been visited. And we only // visit a vertex when we are sure that a // shorter path to that vertex is not // possible if (Q.size() == 0) return ; // Go to the first vertex in Q // and remove it from the Q it = Q.begin(); int next = it->second; Q.erase(it); multiSourceBFSUtil(graph, next); } // This function calculates the distance of // each vertex from nearest source void multiSourceBFS(vector< int > graph[], int n, int sources[], int S) { // a hash array where source[i] = 1 // means vertex i is a source int source[n + 1]; for ( int i = 1; i <= n; i++) source[i] = 0; for ( int i = 0; i <= S - 1; i++) source[sources[i]] = 1; for ( int i = 1; i <= n; i++) { if (source[i]) { dist[i] = 0; Q.insert({ 0, i }); } else { dist[i] = inf; Q.insert({ inf, i }); } } set<pair< int , int > >::iterator itr; // Get the vertex with lowest distance, itr = Q.begin(); // currently one of the sources with distance = 0 int start = itr->second; multiSourceBFSUtil(graph, start); // Printing the distances for ( int i = 1; i <= n; i++) cout << i << " " << dist[i] << endl; } void addEdge(vector< int > graph[], int u, int v) { graph[u].push_back(v); graph[v].push_back(u); } // Driver Code int main() { // Number of vertices int n = 6; vector< int > graph[n + 1]; // Edges addEdge(graph, 1, 2); addEdge(graph, 1, 6); addEdge(graph, 2, 6); addEdge(graph, 2, 3); addEdge(graph, 3, 6); addEdge(graph, 5, 4); addEdge(graph, 6, 5); addEdge(graph, 3, 4); addEdge(graph, 5, 3); // Sources int sources[] = { 1, 5 }; int S = sizeof (sources) / sizeof (sources[0]); multiSourceBFS(graph, n, sources, S); return 0; } |
Java
import java.util.*; class GFG { // This array stores the distances of the vertices // from the nearest source static int [] dist; // This Set contains the vertices not yet visited in // increasing order of distance from the nearest source // calculated till now static Set<Map.Entry<Integer, Integer> > Q = new HashSet<>(); // Util function for Multi-Source BFS static void multiSourceBFSUtil(List<Integer>[] graph, int s) { Iterator<Map.Entry<Integer, Integer> > it; for ( int i = 0 ; i < graph[s].size(); i++) { int v = graph[s].get(i); if (dist[s] + 1 < dist[v]) { // If a shorter path to a vertex is // found than the currently stored // distance replace it in the Q it = Q.iterator(); while (it.hasNext()) { Map.Entry<Integer, Integer> entry = it.next(); if (entry.getValue() == v) { Q.remove(entry); break ; } } dist[v] = dist[s] + 1 ; Q.add(Map.entry(dist[v], v)); } } // Stop when the Q is empty -> All // vertices have been visited. And we only // visit a vertex when we are sure that a // shorter path to that vertex is not // possible if (Q.size() == 0 ) return ; // Go to the first vertex in Q // and remove it from the Q int next = Q.iterator().next().getValue(); Q.remove(Map.entry(dist[next], next)); multiSourceBFSUtil(graph, next); } // This function calculates the distance of // each vertex from nearest source // static void multiSourceBFS(List<Integer>[] graph, int // n, int[] sources) { // // Initialize the dist array with MAX_VALUE // dist = new int[n + 1]; // Arrays.fill(dist, Integer.MAX_VALUE); // // Set the distance of the sources to 0 // for (int i = 0; i < sources.length; i++) { // dist[sources[i]] = 0; // } // for (int i = 1; i <= n; i++) { // Q.add(Map.entry(dist[i], i)); // } static void multiSourceBFS(List<Integer>[] graph, int n, int [] sources) { // Initialize the dist array with n dist = new int [n + 1 ]; Arrays.fill(dist, n); // Set the distance of the sources to 0 for ( int i = 0 ; i < sources.length; i++) { dist[sources[i]] = 0 ; } for ( int i = 1 ; i <= n; i++) { Q.add(Map.entry(dist[i], i)); } // rest of the code is same //... // Get the vertex with lowest distance, int start = Q.iterator().next().getValue(); multiSourceBFSUtil(graph, start); // Printing the distances for ( int i = 1 ; i <= n; i++) System.out.println(i + " " + dist[i]); } static void addEdge(List<Integer>[] graph, int u, int v) { graph[u].add(v); graph[v].add(u); } // Driver Code public static void main(String[] args) { // Number of vertices int n = 6 ; List<Integer>[] graph = new List[n + 1 ]; for ( int i = 0 ; i <= n; i++) { graph[i] = new ArrayList<>(); } // Edges addEdge(graph, 1 , 2 ); addEdge(graph, 1 , 6 ); addEdge(graph, 2 , 6 ); addEdge(graph, 2 , 3 ); addEdge(graph, 3 , 6 ); addEdge(graph, 5 , 4 ); addEdge(graph, 6 , 5 ); addEdge(graph, 3 , 4 ); addEdge(graph, 5 , 3 ); // Sources int [] sources = { 1 , 5 }; multiSourceBFS(graph, n, sources); } } // this code is contributed by devendra |
Python3
# Python3 program to demonstrate # multi-source BFS import math N = 100000 + 1 inf = 1000000 # This array stores the distances of the vertices # from the nearest source inf = math.inf dist = [inf] * N # This Set contains the vertices not yet visited in # increasing order of distance from the nearest source # calculated till now Q = set () # Util function for Multi-Source BFS def multiSourceBFSUtil(graph, s): for i in range ( len (graph[s])): v = graph[s][i] if (dist[s] + 1 < dist[v]) : # If a shorter path to a vertex is # found than the currently stored # distance replace it in the Q if (dist[v],v) in Q: Q.remove((dist[v],v)) dist[v] = dist[s] + 1 Q.add((dist[v], v)) # Stop when the Q is empty . All # vertices have been visited. And we only # visit a vertex when we are sure that a # shorter path to that vertex is not # possible if ( len (Q) = = 0 ): return # Go to the first vertex in Q # and remove it from the Q it = min (Q) next = it[ 1 ] Q.remove(it) multiSourceBFSUtil(graph, next ) # This function calculates the distance of # each vertex from nearest source def multiSourceBFS(graph, n, sources, S): # a hash array where source[i] = 1 # means vertex i is a source source = [ 0 ] * (n + 1 ) for i in range ( 0 ,S): source[sources[i]] = 1 for i in range ( 1 ,n): if (source[i]) : dist[i] = 0 Q.add(( 0 , i)) else : dist[i] = math.inf Q.add((math.inf, i)) # Get the vertex with lowest distance, itr = min (Q) start = itr[ 1 ] Q.remove(itr) multiSourceBFSUtil(graph, start) # Print the distances for i in range ( 1 ,n + 1 ): print (i,dist[i]) def addEdge(graph, u, v): graph[u].append(v) graph[v].append(u) # Driver Code if __name__ = = '__main__' : # Number of vertices n = 6 graph = [[] for _ in range (n + 1 )] # Edges addEdge(graph, 1 , 2 ) addEdge(graph, 1 , 6 ) addEdge(graph, 2 , 6 ) addEdge(graph, 2 , 3 ) addEdge(graph, 3 , 6 ) addEdge(graph, 5 , 4 ) addEdge(graph, 6 , 5 ) addEdge(graph, 3 , 4 ) addEdge(graph, 5 , 3 ) # Sources sources = ( 1 , 5 ) S = len (sources) multiSourceBFS(graph, n, sources, S) |
C#
using System; using System.Collections.Generic; using System.Linq; class GFG { // This array stores the distances of the vertices // from the nearest source static int [] dist; // This Set contains the vertices not yet visited in // increasing order of distance from the nearest source // calculated till now static SortedSet<KeyValuePair< int , int >> Q = new SortedSet<KeyValuePair< int , int >>(Comparer<KeyValuePair< int , int >>.Create( (a, b) => a.Key != b.Key ? a.Key.CompareTo(b.Key) : a.Value.CompareTo(b.Value))); // Util function for Multi-Source BFS static void multiSourceBFSUtil(List< int >[] graph, int s) { foreach ( int v in graph[s]) { if (dist[s] + 1 < dist[v]) { // If a shorter path to a vertex is // found than the currently stored // distance replace it in the Q var entries = Q.Where(entry => entry.Value == v).ToList(); foreach ( var entry in entries) { Q.Remove(entry); } dist[v] = dist[s] + 1; Q.Add( new KeyValuePair< int , int >(dist[v], v)); } } // Stop when the Q is empty -> All // vertices have been visited. And we only // visit a vertex when we are sure that a // shorter path to that vertex is not // possible if (Q.Count == 0) return ; // Go to the first vertex in Q // and remove it from the Q int next = Q.First().Value; Q.Remove( new KeyValuePair< int , int >(dist[next], next)); multiSourceBFSUtil(graph, next); } // This function calculates the distance of // each vertex from nearest source static void multiSourceBFS(List< int >[] graph, int n, int [] sources) { // Initialize the dist array with n dist = new int [n + 1]; Array.Fill(dist, n); // Set the distance of the sources to 0 for ( int i = 0; i < sources.Length; i++) { dist[sources[i]] = 0; } for ( int i = 1; i <= n; i++) { Q.Add( new KeyValuePair< int , int >(dist[i], i)); } // rest of the code is same //... // Get the vertex with lowest distance, int start = Q.First().Value; multiSourceBFSUtil(graph, start); // Printing the distances for ( int i = 1; i <= n; i++) Console.WriteLine(i + " " + dist[i]); } static void addEdge(List< int >[] graph, int u, int v) { graph[u].Add(v); graph[v].Add(u); } // Driver Code public static void Main( string [] args) { // Number of vertices int n = 6; List< int >[] graph = new List< int >[n + 1]; for ( int i = 0; i <= n; i++) { graph[i] = new List< int >(); } // Edges addEdge(graph, 1, 2); addEdge(graph, 1, 6); addEdge(graph, 2, 6); addEdge(graph, 2, 3); addEdge(graph, 3, 6); addEdge(graph, 5, 4); int [] sources = new int [] { 1, 3, 5 }; multiSourceBFS(graph, n, sources); } } |
Javascript
const dist = []; const Q = new Set(); function multiSourceBFSUtil(graph, s) { for (let i = 0; i < graph[s].length; i++) { let v = graph[s][i]; if (dist[s] + 1 < dist[v]) { for (let entry of Q.entries()) { if (entry[1] === v) { Q. delete (entry); break ; } } dist[v] = dist[s] + 1; Q.add([dist[v], v]); } } if (Q.size === 0) { return ; } let next = [...Q][0][1]; Q. delete ([...Q][0]); multiSourceBFSUtil(graph, next); } function multiSourceBFS(graph, n, sources) { dist.length = n + 1; dist.fill(n); for (let i = 0; i < sources.length; i++) { dist[sources[i]] = 0; } for (let i = 1; i <= n; i++) { Q.add([dist[i], i]); } let start = [...Q][0][1]; multiSourceBFSUtil(graph, start); for (let i = 1; i <= n; i++) { console.log(i + " " + dist[i]); } } function addEdge(graph, u, v) { graph[u].push(v); graph[v].push(u); } const n = 6; const graph = new Array(n + 1); for (let i = 0; i <= n; i++) { graph[i] = []; } addEdge(graph, 1, 2); addEdge(graph, 1, 6); addEdge(graph, 2, 6); addEdge(graph, 2, 3); addEdge(graph, 3, 6); addEdge(graph, 5, 4); addEdge(graph, 6, 5); addEdge(graph, 3, 4); addEdge(graph, 5, 3); const sources = [1, 5]; multiSourceBFS(graph, n, sources); // this code is contributed by writer |
1 0 2 1 3 1 4 1 5 0 6 1
Complexity Analysis:
- Time Complexity: O(E.logV)
- Auxiliary Space: O(V)
More Efficient Approach: An even better method is to use the Multisource BFS which is a modification of BFS.We will put the all source vertices to the queue at first rather than a single vertex which was in case of standard BFS.This way Multisource BFS will first visit all the source vertices. After that it will visit the vertices which are at a distance of 1 from all source vertices, then at a distance of 2 from all source vertices and so on and so forth.
Below is the implementation of the above approach:
C++
// C++ program to demonstrate Multi-source BFS #include<bits/stdc++.h> using namespace std; #define N 1000000 // This array stores the distances of the vertices // from the nearest source int dist[N]; //This boolean array is true if the current vertex // is visited otherwise it is false bool visited[N]; void addEdge(vector< int > graph[], int u, int v) { //Function to add 2 edges in an undirected graph graph[u].push_back(v); graph[v].push_back(u); } // Multisource BFS Function void Multisource_BFS(vector< int > graph[],queue< int >q) { while (!q.empty()) { int k = q.front(); q.pop(); for ( auto i:graph[k]) { if (!visited[i]) { // Pushing the adjacent unvisited vertices // with distance from current source = this // vertex's distance + 1 q.push(i); dist[i] = dist[k] + 1; visited[i] = true ; } } } } // This function calculates the distance of each // vertex from nearest source void nearestTown(vector< int > graph[], int n, int sources[], int s) { //Create a queue for BFS queue< int > q; //Mark all the source vertices as visited and enqueue it for ( int i = 0;i < s; i++) { q.push(sources[i]); visited[sources[i]]= true ; } Multisource_BFS(graph,q); //Printing the distances for ( int i = 1; i <= n; i++) { cout<< i << " " << dist[i] << endl; } } // Driver code int main() { // Number of vertices int n = 6; vector< int > graph[n + 1]; // Edges addEdge(graph, 1, 2); addEdge(graph, 1, 6); addEdge(graph, 2, 6); addEdge(graph, 2, 3); addEdge(graph, 3, 6); addEdge(graph, 5, 4); addEdge(graph, 6, 5); addEdge(graph, 3, 4); addEdge(graph, 5, 3); // Sources int sources[] = { 1, 5 }; int S = sizeof (sources) / sizeof (sources[0]); nearestTown(graph, n, sources, S); return 0; } |
Java
// Java program to demonstrate Multi-source BFS import java.util.*; import java.math.*; class GFG{ static int N = 1000000 ; // This array stores the distances of the vertices // from the nearest source static int dist[] = new int [N]; //This boolean array is true if the current vertex // is visited otherwise it is false static boolean visited[] = new boolean [N]; static void addEdge(ArrayList<Integer> graph[], int u, int v) { // Function to add 2 edges in an undirected graph graph[u].add(v); graph[v].add(u); } // Multisource BFS Function static void Multisource_BFS(ArrayList<Integer> graph[], Queue<Integer>q) { while (!q.isEmpty()) { int k = q.peek(); q.poll(); for ( int i:graph[k]) { if (!visited[i]) { // Pushing the adjacent unvisited vertices // with distance from current source = this // vertex's distance + 1 q.add(i); dist[i] = dist[k] + 1 ; visited[i] = true ; } } } } // This function calculates the distance of each // vertex from nearest source static void nearestTown(ArrayList<Integer> graph[], int n, int sources[], int s) { // Create a queue for BFS Queue<Integer> q= new LinkedList<>(); // Mark all the source vertices as // visited and enqueue it for ( int i = 0 ;i < s; i++) { q.add(sources[i]); visited[sources[i]] = true ; } Multisource_BFS(graph, q); // Printing the distances for ( int i = 1 ; i <= n; i++) { System.out.println(i + " " + dist[i]); } } // Driver code public static void main(String args[]) { // Number of vertices int n = 6 ; @SuppressWarnings ( "unchecked" ) ArrayList<Integer> graph[] = new ArrayList[N + 1 ]; for ( int i = 0 ; i < graph.length; i++) graph[i] = new ArrayList<Integer>(); // Edges addEdge(graph, 1 , 2 ); addEdge(graph, 1 , 6 ); addEdge(graph, 2 , 6 ); addEdge(graph, 2 , 3 ); addEdge(graph, 3 , 6 ); addEdge(graph, 5 , 4 ); addEdge(graph, 6 , 5 ); addEdge(graph, 3 , 4 ); addEdge(graph, 5 , 3 ); // Sources int sources[] = { 1 , 5 }; int S = sources.length; nearestTown(graph, n, sources, S); } } // This code is contributed by Debojyoti Mandal |
Python3
# Python3 program to demonstrate Multi-source BFS N = 1000000 # This array stores the distances of the vertices # from the nearest source dist = [ 0 ] * (N) # This boolean array is true if the current vertex # is visited otherwise it is false visited = [ False ] * (N) def addEdge(graph, u, v): # Function to add 2 edges in an undirected graph graph[u].append(v); graph[v].append(u) # Multisource BFS Function def Multisource_BFS(graph, q): while ( len (q) > 0 ): k = q[ 0 ] q.pop( 0 ) for i in range ( len (graph[k])): if not visited[graph[k][i]]: # Pushing the adjacent unvisited vertices # with distance from current source = this # vertex's distance + 1 q.append(graph[k][i]) dist[graph[k][i]] = dist[k] + 1 visited[graph[k][i]] = True # This function calculates the distance of each # vertex from nearest source def nearestTown(graph, n, sources, s): # Create a queue for BFS q = [] # Mark all the source vertices as visited and enqueue it for i in range (s): q.append(sources[i]) visited[sources[i]] = True Multisource_BFS(graph,q) # Printing the distances for i in range ( 1 , n + 1 ): print (i, " " , dist[i], sep = "") # Number of vertices n = 6 graph = [] for i in range (n + 1 ): graph.append([]) # Edges addEdge(graph, 1 , 2 ) addEdge(graph, 1 , 6 ) addEdge(graph, 2 , 6 ) addEdge(graph, 2 , 3 ) addEdge(graph, 3 , 6 ) addEdge(graph, 5 , 4 ) addEdge(graph, 6 , 5 ) addEdge(graph, 3 , 4 ) addEdge(graph, 5 , 3 ) # Sources sources = [ 1 , 5 ] S = len (sources) nearestTown(graph, n, sources, S) # This code is contributed by rameshtravel07. |
C#
// C# program to demonstrate Multi-source BFS using System; using System.Collections.Generic; class GFG { static int N = 1000000; // This array stores the distances of the vertices // from the nearest source static int [] dist = new int [N]; //This boolean array is true if the current vertex // is visited otherwise it is false static bool [] visited = new bool [N]; static void addEdge(List<List< int >> graph, int u, int v) { // Function to add 2 edges in an undirected graph graph[u].Add(v); graph[v].Add(u); } // Multisource BFS Function static void Multisource_BFS(List<List< int >> graph, List< int > q) { while (q.Count > 0) { int k = q[0]; q.RemoveAt(0); foreach ( int i in graph[k]) { if (!visited[i]) { // Pushing the adjacent unvisited vertices // with distance from current source = this // vertex's distance + 1 q.Add(i); dist[i] = dist[k] + 1; visited[i] = true ; } } } } // This function calculates the distance of each // vertex from nearest source static void nearestTown(List<List< int >> graph, int n, int [] sources, int s) { // Create a queue for BFS List< int > q = new List< int >(); // Mark all the source vertices as // visited and enqueue it for ( int i = 0;i < s; i++) { q.Add(sources[i]); visited[sources[i]] = true ; } Multisource_BFS(graph, q); // Printing the distances for ( int i = 1; i <= n; i++) { Console.WriteLine(i + " " + dist[i]); } } static void Main() { // Number of vertices int n = 6; List<List< int >> graph = new List<List< int >>(); for ( int i = 0; i < N + 1; i++) graph.Add( new List< int >()); // Edges addEdge(graph, 1, 2); addEdge(graph, 1, 6); addEdge(graph, 2, 6); addEdge(graph, 2, 3); addEdge(graph, 3, 6); addEdge(graph, 5, 4); addEdge(graph, 6, 5); addEdge(graph, 3, 4); addEdge(graph, 5, 3); // Sources int [] sources = { 1, 5 }; int S = sources.Length; nearestTown(graph, n, sources, S); } } // This code is contributed by divyesh072019. |
Javascript
<script> // Javascript program to demonstrate Multi-source BFS let N = 1000000; // This array stores the distances of the vertices // from the nearest source let dist = new Array(N); dist.fill(0); // This boolean array is true if the current vertex // is visited otherwise it is false let visited = new Array(N); visited.fill( false ); function addEdge(graph, u, v) { // Function to add 2 edges in an undirected graph graph[u].push(v); graph[v].push(u); } // Multisource BFS Function function Multisource_BFS(graph, q) { while (q.length > 0) { let k = q[0]; q.shift(); for (let i = 0; i < graph[k].length; i++) { if (!visited[graph[k][i]]) { // Pushing the adjacent unvisited vertices // with distance from current source = this // vertex's distance + 1 q.push(graph[k][i]); dist[graph[k][i]] = dist[k] + 1; visited[graph[k][i]] = true ; } } } } // This function calculates the distance of each // vertex from nearest source function nearestTown(graph, n, sources, s) { // Create a queue for BFS let q = []; // Mark all the source vertices as visited and enqueue it for (let i = 0;i < s; i++) { q.push(sources[i]); visited[sources[i]]= true ; } Multisource_BFS(graph,q); // Printing the distances for (let i = 1; i <= n; i++) { document.write(i + " " + dist[i] + "</br>" ); } } // Number of vertices let n = 6; let graph = []; for (let i = 0; i < n + 1; i++) { graph.push([]); } // Edges addEdge(graph, 1, 2); addEdge(graph, 1, 6); addEdge(graph, 2, 6); addEdge(graph, 2, 3); addEdge(graph, 3, 6); addEdge(graph, 5, 4); addEdge(graph, 6, 5); addEdge(graph, 3, 4); addEdge(graph, 5, 3); // Sources let sources = [ 1, 5 ]; let S = sources.length; nearestTown(graph, n, sources, S); // This code is contributed by decode2207. </script> |
1 0 2 1 3 1 4 1 5 0 6 1
Complexity Analysis:
- Time Complexity: O(V+E)
- Auxiliary Space: O(V)
Please Login to comment...