📜  使用广度优先搜索实现供水问题

📅  最后修改于: 2021-09-08 12:36:11             🧑  作者: Mango

给定使用N-1条道路连接的N个城市。在城市[i, i+1] 之间,从 1 到 N-1 的所有i都存在一条边。
任务是建立供水连接。在一个城市设置供水系统,然后通过公路运输将水从该城市输送到其他城市。某些城市被封锁,这意味着水无法通过该特定城市。确定可以供水的最大城市数量。
输入格式:

  • 第一行包含一个整数 >strong>N 表示城市的数量。
  • 接下来的 N-1 行包含两个空格分隔的整数uv表示之间的道路
    城市 u 和 v。
  • 下一行包含 N 个空格分隔的整数,如果第i 个城市是 1
    阻塞,否则为0。

例子:

方法:
在这篇文章中,讨论了基于 BFS 的解决方案。
我们对每个城市进行广度优先搜索并检查两件事:城市没有被封锁,城市没有被访问。如果这两个条件都为真,那么我们从该城市运行广度优先搜索并计算可以供水的城市数量。
该解决方案也可以使用深度优先搜索来实现。
下面是上述方法的实现:

C++
// C++ program to solve water
// supply problem using BFS
 
#include 
#include 
#include 
using namespace std;
 
// Function to perform BFS
int bfsUtil(int v[], bool vis[], vector adj[],
                                            int src)
{
    // Mark current source visited
    vis[src] = true;
     
    queue 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 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 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<


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 adj[],
                   int src)
{
     
    // Mark current source visited
    vis[src] = true;
     
    // Queue for BFS
    Queue 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 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 []adj = new Vector[N + 1];
    for (int i = 0; i < adj.length; i++)
        adj[i] = new Vector();
         
    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 []adj,
                   int src)
{
  // Mark current source visited
  vis[src] = true;
 
  // Queue for BFS
  Queue q = new Queue();
 
  // 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 []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 []adj = new List[N + 1];
  for (int i = 0; i < adj.Length; i++)
    adj[i] = new List();
 
  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


输出:

2



如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live