Implementing Water Supply Problem using Breadth First Search


In this problem, we will find the maximum number of cities to which we can supply water.

We can consider this problem as a graph traversing the blocked node. So, we can use the breadth-first search algorithm to find the maximum number of connected cities.

Problem Statement

We have given the total N cities. Also, we have given an edge between two cities; all cities are connected with any other single or multiple cities. We need to set up the water supply connection in each city. We have also given the blocked[] array containing the 0 and 1 values. The value 1 means the city is blocked. So, we can't pass the water through that particular city. The value 0 means we can pass the water through the city. We need to find the maximum number of cities to which we can supply the water.

Sample Examples

Input

cities = 5; roads = 1-> 2, 2 -> 3, 3-> 4, 4-> 5; blocked[] = {0, 1, 0, 0, 1};

Output

4

Explanation

If we start supplying water from the 3rd or 4th city, we can supply water to 2, 3, 4, and 5th cities.

Input

cities = 5; roads = 1-> 2, 2 -> 3, 3-> 4, 4-> 5; blocked[] = {1, 1, 1, 1, 1};

Output

1

Explanation

When all cities are blocked, we can supply water to any single city which is connected to the water connection.

Input

cities = 6; roads = 1-> 2, 2 -> 3, 2 -> 6, 3-> 4, 4-> 5; blocked[] = {1, 0, 0, 1, 0, 1};

Output

4

Explanation

We can connect the water connection to the 2nd city to supply water to the 1st, 2nd, 3rd, and 4th cities.

Approach

In this approach, we will find all sets of connected cities using the breadth-first search algorithm. After that, we can take the size of the maximum connecting the maximum cities as an answer.

Algorithm

  • Step 1 − Initialize the visited[] array with a false boolean value to track whether the city is visited while BFS traversal.

  • Step 2 − Initialize the maxi with 1 to track the maximum connected cities.

  • Step 3 − Travese each city using the loop. If the city is not blocked and has not been visited previously, call the findConnectedCities() function to find all connected cities to the current city.

  • Step 3.1 − In the findConnectedCities() function, mark the current city as visited.

  • Step 3.2 − Define the queue and insert the source city into the queue. Also, initialize the 'cnt' with 0 to store the number of connected cities.

  • Step 3.3 − Travese the queue while it is not empty.

  • Step 3.3.1 − Pop the first element of the queue.

  • Step 3.3.2 − Traverse all adjacent cities of the current city.

  • Step 3.3.3 − If the city is not visited or not blocked, increment 'cnt' by 1, mark it as visited, and insert it into the queue.

  • Step 3.3.4 − If the city is not visited and the city is blocked, increment 'cnt' by 1.

  • Step 3.3.5 − Pop the city from the queue.

  • Step 3.4 − Return cnt + 1. Here, we add 1 to count the source city itself.

  • Step 4 − If the returned value from the function is greater than a maxi, update the maxi with the new value.

  • Step 5 − Return maxi.

Example

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int findConnectedCities(int blocked[], bool visited[], vector<int> roads[], int source) {
   visited[source] = true;
   queue<int> que;
   que.push(source);
   int cnt = 0;
   while (!que.empty()) {
      int temp = que.front();
      for (int p = 0; p < roads[temp].size(); p++) {
         // When the neighboring city is not blocked and visited
         if (!visited[roads[temp][p]] && blocked[roads[temp][p]] == 0) {
            cnt++;
            visited[roads[temp][p]] = true;
            que.push(roads[temp][p]);
         }
         // We can supply water to the blocked city, but the block city can't supply water to other cities
         else if (!visited[roads[temp][p]] && blocked[roads[temp][p]] == 1) {
            cnt++;
         }
      }
      que.pop();
   }
   return cnt + 1;
}
int maxNumberCities(int cities, int blocked[], vector<int> roads[]) {
   bool visited[cities + 1];
   int maxi = 1;
   for (int p = 1; p <= cities; p++)
      visited[p] = false;
   // Start BFS for each city
   for (int p = 1; p <= cities; p++) {
      // When the city is not blocked and not visited
      if (blocked[p] == 0 && !visited[p]) {
         int temp = findConnectedCities(blocked, visited, roads, p);
         if (temp > maxi) {
            maxi = temp;
         }
      }
   }
   return maxi;
}
int main() {
   int cities = 5;
   vector<int> roads[cities + 1];
   // To store road connection
   roads[1].push_back(2);
   roads[2].push_back(1);
   roads[2].push_back(3);
   roads[3].push_back(2);
   roads[3].push_back(4);
   roads[4].push_back(3);
   roads[3].push_back(5);
   roads[5].push_back(3);
   // To store whether the city is blocked or not
   int blocked[] = {0, 1, 0, 0, 1};
   cout << "The maximum number of cities to which we can supply water is " << maxNumberCities(cities, blocked, roads);
   return 0;
}

Output

The maximum number of cities to which we can supply water is 4
  • Time complexity − O(N) to traverse all cities.

  • Space complexity − O(N) to store cities in the queue.

Conclusion

The given problem is very similar to finding the size of the largest Island. In the Island problem also, we start BFS traversal from the unvisited nodes and find the connected nodes.

Updated on: 25-Aug-2023

48 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements