Open In App

Implementing Water Supply Problem using Breadth First Search

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

Given N cities that are connected using N-1 roads. Between Cities [i, i+1], there exists an edge for all i from 1 to N-1.
The task is to set up a connection for water supply. Set the water supply in one city and water gets transported from it to other cities using road transport. Certain cities are blocked which means that water cannot pass through that particular city. Determine the maximum number of cities to which water can be supplied.
Input format:

  • The first line contains an integer >strong>N denoting the number of cities.
  • The next N-1 lines contain two space-separated integers u v denoting a road between 
    city u and v.
  • The next line contains N space-separated integers where it is 1 if the ith city is 
    blocked, else it is 0.

Examples:

Input : 

1 2 
2 3 
3 4 
0 1 1 0 
Output : 

Explanation : If city 1 is chosen, then water is supplied from 
city 1 to 2. If city 4 is chosen, water is supplied from city 4 to 3 
hence maximum of 2 cities can be supplied with water.
Input : 

1 2 
2 3 
3 4 
4 5 
5 6 
6 7 
0 1 1 0 0 0 0 
Output : 

Explanation : If city 1 is chosen than water is supplied from 
city 1 to 2 or if city 4 is chosen water is supplied from city 4 to 
3, 5, 6 and 7 hence maximum of 5 cities are supplied with water.

Approach:
In this post, a BFS based solution is discussed.
We run a breadth-first search on each city and check for two things: The city is not blocked and the city is not visited. If both these conditions return true then we run a breadth-first search from that city and count the number of cities up to which water can be supplied. 
This solution can also be achieved using a depth-first search.
Below is the implementation of the above approach:

C++




// C++ program to solve water
// supply problem using BFS
 
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
 
// Function to perform BFS
int bfsUtil(int v[], bool vis[], vector<int> adj[],
                                            int src)
{
    // Mark current source visited
    vis[src] = true;
     
    queue<int> q; //Queue for BFS
    q.push(src); // Push src to queue
     
    int count = 0;
    while (!q.empty()) {
         
        int p = q.front();
         
        for (int i = 0; i < adj[p].size(); i++) {
             
            // When the adjacent city not visited and
            // not blocked, push city in the queue.
            if (!vis[adj[p][i]] && v[adj[p][i]] == 0) {
                count++;
                vis[adj[p][i]] = true;
                q.push(adj[p][i]);
            }
             
            // when the adjacent city is not visited
            // but blocked so the blocked city is
            // not pushed in queue
            else if (!vis[adj[p][i]] && v[adj[p][i]] == 1) {
                count++;
            }
        }
        q.pop();
    }
     
    return count + 1;
}
 
// Utility function to perform BFS
int bfs(int N, int v[], vector<int> adj[])
{
    bool vis[N + 1];
    int max = 1, res;
     
    // marking visited array false
    for (int i = 1; i <= N; i++)
        vis[i] = false;
         
    // Check for each and every city
    for (int i = 1; i <= N; i++) {
        // Checks that city is not blocked
        // and not visited.
        if (v[i] == 0 && !vis[i]) {
            res = bfsUtil(v, vis, adj, i);
            if (res > max) {
                max = res;
            }
        }
    }
     
    return max;
}
 
// Driver Code
int main()
{
    int N = 4; // Denotes the number of cities
    vector<int> adj[N + 1];
    int v[N + 1];
 
    // Adjacency list denoting road
    // between city u and v
    adj[1].push_back(2);
    adj[2].push_back(1);
    adj[2].push_back(3);
    adj[3].push_back(2);
    adj[3].push_back(4);
    adj[4].push_back(3);
 
    // array for storing whether ith
    // city is blocked or not
    v[1] = 0;
    v[2] = 1;
    v[3] = 1;
    v[4] = 0;
     
    cout<<bfs(N, v, adj);
     
    return 0;
}


Java




// Java program to solve water
// supply problem using BFS
import java.util.*;
 
class GFG{
 
// Function to perform BFS
static int bfsUtil(int v[], boolean vis[],
                   Vector<Integer> adj[],
                   int src)
{
     
    // Mark current source visited
    vis[src] = true;
     
    // Queue for BFS
    Queue<Integer> q = new LinkedList<>();
     
    // Push src to queue
    q.add(src);
     
    int count = 0;
    while (!q.isEmpty())
    {
        int p = q.peek();
         
        for(int i = 0; i < adj[p].size(); i++)
        {
             
            // When the adjacent city not
            // visited and not blocked, push
            // city in the queue.
            if (!vis[adj[p].get(i)] &&
                   v[adj[p].get(i)] == 0)
            {
                count++;
                vis[adj[p].get(i)] = true;
                q.add(adj[p].get(i));
            }
             
            // When the adjacent city is not visited
            // but blocked so the blocked city is
            // not pushed in queue
            else if (!vis[adj[p].get(i)] &&
                        v[adj[p].get(i)] == 1)
            {
                count++;
            }
        }
        q.remove();
    }
    return count + 1;
}
 
// Utility function to perform BFS
static int bfs(int N, int v[],
        Vector<Integer> adj[])
{
    boolean []vis = new boolean[N + 1];
    int max = 1, res;
     
    // Marking visited array false
    for(int i = 1; i <= N; i++)
        vis[i] = false;
         
    // Check for each and every city
    for(int i = 1; i <= N; i++)
    {
         
        // Checks that city is not blocked
        // and not visited.
        if (v[i] == 0 && !vis[i])
        {
            res = bfsUtil(v, vis, adj, i);
            if (res > max)
            {
                max = res;
            }
        }
    }
    return max;
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Denotes the number of cities
    int N = 4;
     
    @SuppressWarnings("unchecked")
    Vector<Integer> []adj = new Vector[N + 1];
    for (int i = 0; i < adj.length; i++)
        adj[i] = new Vector<Integer>();
         
    int []v = new int[N + 1];
 
    // Adjacency list denoting road
    // between city u and v
    adj[1].add(2);
    adj[2].add(1);
    adj[2].add(3);
    adj[3].add(2);
    adj[3].add(4);
    adj[4].add(3);
 
    // Array for storing whether ith
    // city is blocked or not
    v[1] = 0;
    v[2] = 1;
    v[3] = 1;
    v[4] = 0;
     
    System.out.print(bfs(N, v, adj));
}
}
 
// This code is contributed by Princi Singh


Python3




# Python3 program to solve water
# supply problem using BFS
 
# Function to perform BFS
def bfsUtil(v, vis, adj, src):
     
    # Mark current source visited
    vis[src] = True
 
    # Queue for BFS   
    q = []
     
    # Push src to queue
    q.append(src)
     
    count = 0
    while (len(q) != 0):
        p = q[0]
         
        for i in range(len(adj[p])):
             
            # When the adjacent city not visited and
            # not blocked, push city in the queue.
            if (vis[adj[p][i]] == False and v[adj[p][i]] == 0):
                count += 1
                vis[adj[p][i]] = True
                q.push(adj[p][i])
             
            # when the adjacent city is not visited
            # but blocked so the blocked city is
            # not pushed in queue
            elif(vis[adj[p][i]] == False and v[adj[p][i]] == 1):
                count += 1
        q.remove(q[0])
     
    return count + 1
 
# Utility function to perform BFS
def bfs(N, v, adj):
    vis = [ 0 for i in range(N + 1)]
    mx = 1
     
    # marking visited array false
    for i in range(1, N + 1, 1):
        vis[i] = False
         
    # Check for each and every city
    for i in range(1, N + 1, 1):
         
        # Checks that city is not blocked
        # and not visited.
        if (v[i] == 0 and vis[i] == False):
            res = bfsUtil(v, vis, adj, i)
            if (res > mx):
                mx = res
 
    return mx
 
# Driver Code
if __name__ == '__main__':
    N = 4
     
    # Denotes the number of cities
    adj = [[] for i in range(N + 1)]
    v = [0 for i in range(N + 1)]
 
    # Adjacency list denoting road
    # between city u and v
    adj[1].append(2)
    adj[2].append(1)
    adj[2].append(3)
    adj[3].append(2)
    adj[3].append(4)
    adj[4].append(3)
 
    # array for storing whether ith
    # city is blocked or not
    v[1] = 0
    v[2] = 1
    v[3] = 1
    v[4] = 0
     
    print(bfs(N, v, adj))
 
# This code is contributed by Bhupendra_Singh


C#




// C# program to solve water
// supply problem using BFS
using System;
using System.Collections.Generic;
class GFG{
 
// Function to perform BFS
static int bfsUtil(int []v, bool []vis,
                   List<int> []adj,
                   int src)
{
  // Mark current source visited
  vis[src] = true;
 
  // Queue for BFS
  Queue<int> q = new Queue<int>();
 
  // Push src to queue
  q.Enqueue(src);
 
  int count = 0;
  while (q.Count != 0)
  {
    int p = q.Peek();
    for(int i = 0; i < adj[p].Count; i++)
    {
      // When the adjacent city not
      // visited and not blocked, push
      // city in the queue.
      if (!vis[adj[p][i]] &&
          v[adj[p][i]] == 0)
      {
        count++;
        vis[adj[p][i]] = true;
        q.Enqueue(adj[p][i]);
      }
 
      // When the adjacent city is not visited
      // but blocked so the blocked city is
      // not pushed in queue
      else if (!vis[adj[p][i]] &&
               v[adj[p][i]] == 1)
      {
        count++;
      }
    }
    q.Dequeue();
  }
  return count + 1;
}
 
// Utility function to perform BFS
static int bfs(int N, int []v,
               List<int> []adj)
{
  bool []vis = new bool[N + 1];
  int max = 1, res;
 
  // Marking visited array false
  for(int i = 1; i <= N; i++)
    vis[i] = false;
 
  // Check for each and every city
  for(int i = 1; i <= N; i++)
  {
    // Checks that city is not blocked
    // and not visited.
    if (v[i] == 0 && !vis[i])
    {
      res = bfsUtil(v, vis, adj, i);
      if (res > max)
      {
        max = res;
      }
    }
  }
  return max;
}
 
// Driver Code
public static void Main(String[] args)
{
  // Denotes the number of cities
  int N = 4;
 
  List<int> []adj = new List<int>[N + 1];
  for (int i = 0; i < adj.Length; i++)
    adj[i] = new List<int>();
 
  int []v = new int[N + 1];
 
  // Adjacency list denoting road
  // between city u and v
  adj[1].Add(2);
  adj[2].Add(1);
  adj[2].Add(3);
  adj[3].Add(2);
  adj[3].Add(4);
  adj[4].Add(3);
 
  // Array for storing whether ith
  // city is blocked or not
  v[1] = 0;
  v[2] = 1;
  v[3] = 1;
  v[4] = 0;
 
  Console.Write(bfs(N, v, adj));
}
}
 
// This code is contributed by Princi Singh


Javascript




<script>
    // Javascript program to solve water
    // supply problem using BFS
     
    // Function to perform BFS
    function bfsUtil(v, vis, adj, src)
    {
 
        // Mark current source visited
        vis[src] = true;
 
        // Queue for BFS
        let q = [];
 
        // Push src to queue
        q.push(src);
 
        let count = 0;
        while (q.length > 0)
        {
            let p = q[0];
 
            for(let i = 0; i < adj[p].length; i++)
            {
 
                // When the adjacent city not
                // visited and not blocked, push
                // city in the queue.
                if (!vis[adj[p][i]] &&
                       v[adj[p][i]] == 0)
                {
                    count++;
                    vis[adj[p][i]] = true;
                    q.add(adj[p][i]);
                }
 
                // When the adjacent city is not visited
                // but blocked so the blocked city is
                // not pushed in queue
                else if (!vis[adj[p][i]] &&
                            v[adj[p][i]] == 1)
                {
                    count++;
                }
            }
            q.shift();
        }
        return count + 1;
    }
 
    // Utility function to perform BFS
    function bfs(N, v, adj)
    {
        let vis = new Array(N + 1);
        let max = 1, res;
 
        // Marking visited array false
        for(let i = 1; i <= N; i++)
            vis[i] = false;
 
        // Check for each and every city
        for(let i = 1; i <= N; i++)
        {
 
            // Checks that city is not blocked
            // and not visited.
            if (v[i] == 0 && !vis[i])
            {
                res = bfsUtil(v, vis, adj, i);
                if (res > max)
                {
                    max = res;
                }
            }
        }
        return max;
    }
     
    // Denotes the number of cities
    let N = 4;
      
    let adj = new Array(N + 1);
    for (let i = 0; i < adj.length; i++)
        adj[i] = [];
          
    let v = new Array(N + 1);
  
    // Adjacency list denoting road
    // between city u and v
    adj[1].push(2);
    adj[2].push(1);
    adj[2].push(3);
    adj[3].push(2);
    adj[3].push(4);
    adj[4].push(3);
  
    // Array for storing whether ith
    // city is blocked or not
    v[1] = 0;
    v[2] = 1;
    v[3] = 1;
    v[4] = 0;
      
    document.write(bfs(N, v, adj));
     
    // This code is contributed by divyeshrabadiya07.
 
</script>


Output:

2


Last Updated : 20 Jul, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads