📜  供水问题

📅  最后修改于: 2021-05-06 23:27:42             🧑  作者: Mango

殖民地中的每个房屋最多只能有一个管道进入,最多也有一个管道从其中出来。储罐和水龙头的安装方式应使每户只有一根出水管但没有进水管的房屋都在其屋顶上安装储水箱,每户只有一根进水管而没有出水管的房屋都应有水龙头。
给定两个整数n和p,分别表示房屋数量和管道数量。房屋之间的管道连接包含三个输入值: a_ib_id_i,表示从房屋a_i到房屋b_i的直径为d_i的管道,从而找到了网络的有效解决方案。
输出将包含安装在第一行中的储罐和水龙头对的数量t ,接下来的t行包含三个整数:储罐的房屋数量,水龙头的房屋数量以及它们之间的最小管道直径。

例子:

Input : 4 2
        1 2 60
        3 4 50
Output :2
        1 2 60
        3 4 50
Explanation:
Connected components are: 
1->2 and 3->4
Therefore, our answer is 2 followed by
1 2 60 and 3 4 50.

Input :9 6
       7 4 98
       5 9 72
       4 6 10
       2 8 22
       9 7 17
       3 1 66
Output :3
        2 8 22
        3 1 66
        5 6 10
Explanation:
Connected components are 3->1, 
5->9->7->4->6 and 2->8. 
Therefore, our answer is 3 followed by
2 8 22, 3 1 66, 5 6 10

方法:
从适当的房屋执行DFS,以找到所有不同的连接组件。不同的连接组件数是我们的答案t。
输出的接下来的t行是连接的组件的起点,连接的组件的终点以及每行中从连接的组件的起点到终点的最小直径。
由于只能将储罐安装在有出水管而没有进水管的房屋上,因此,这些房屋是启动DFS的合适房屋,即从此类未访问房屋进行DFS。

下面是上述方法的实现:

C++
// C++ program to find efficient
// solution for the network
#include 
using namespace std;
  
// number of houses and number
// of pipes
int n, p;
  
// Array rd stores the 
// ending vertex of pipe
int rd[1100];
  
// Array wd stores the value 
// of diameters between two pipes
int wt[1100];
  
// Array cd stores the 
// starting end of pipe
int cd[1100];
  
// Vector a, b, c are used
// to store the final output
vector a;
vector b;
vector c;
  
int ans;
  
int dfs(int w)
{
    if (cd[w] == 0)
        return w;
    if (wt[w] < ans)
        ans = wt[w];
    return dfs(cd[w]);
}
  
// Function performing calculations.
void solve(int arr[][3])
{
    int i = 0;
  
    while (i < p) {
          
        int q = arr[i][0], h = arr[i][1],
            t = arr[i][2];
          
        cd[q] = h;
        wt[q] = t;
        rd[h] = q;
        i++;
    }
      
    a.clear();
    b.clear();
    c.clear();
      
    for (int j = 1; j <= n; ++j)
      
        /*If a pipe has no ending vertex 
        but has starting vertex i.e is 
        an outgoing pipe then we need 
        to start DFS with this vertex.*/
        if (rd[j] == 0 && cd[j]) {
            ans = 1000000000;
            int w = dfs(j);
              
            // We put the details of component
            // in final output array
            a.push_back(j);
            b.push_back(w);
            c.push_back(ans);
        }
          
    cout << a.size() << endl;
    for (int j = 0; j < a.size(); ++j)
        cout << a[j] << " " << b[j] 
             << " " << c[j] << endl;
}
  
// driver function
int main()
{
    n = 9, p = 6;
  
    memset(rd, 0, sizeof(rd));
    memset(cd, 0, sizeof(cd));
    memset(wt, 0, sizeof(wt));
  
    int arr[][3] = { { 7, 4, 98 },
                    { 5, 9, 72 },
                    { 4, 6, 10 },
                    { 2, 8, 22 },
                    { 9, 7, 17 },
                    { 3, 1, 66 } };
  
    solve(arr);
    return 0;
}


Java
// Java program to find efficient
// solution for the network
import java.util.*;
  
class GFG {
      
    // number of houses and number
    // of pipes
    static int n, p;
  
    // Array rd stores the 
    // ending vertex of pipe
    static int rd[] = new int[1100];
  
    // Array wd stores the value 
    // of diameters between two pipes
    static int wt[] = new int[1100];
  
    // Array cd stores the 
    // starting end of pipe
    static int cd[] = new int[1100];
  
    // arraylist a, b, c are used
    // to store the final output
    static List  a = 
              new ArrayList();
                
    static List  b = 
              new ArrayList();
                
    static List  c = 
              new ArrayList();
      
    static int ans;
      
    static int dfs(int w)
    {
        if (cd[w] == 0)
            return w;
        if (wt[w] < ans)
            ans = wt[w];
              
        return dfs(cd[w]);
    }
  
    // Function to perform calculations.
    static void solve(int arr[][])
    {
        int i = 0;
      
        while (i < p)
        {
              
            int q = arr[i][0];
            int h = arr[i][1];
            int t = arr[i][2];
              
            cd[q] = h;
            wt[q] = t;
            rd[h] = q;
            i++;
        }
          
        a=new ArrayList();
        b=new ArrayList();
        c=new ArrayList();
          
        for (int j = 1; j <= n; ++j)
          
            /*If a pipe has no ending vertex 
            but has starting vertex i.e is 
            an outgoing pipe then we need 
            to start DFS with this vertex.*/
            if (rd[j] == 0 && cd[j]>0) {
                ans = 1000000000;
                int w = dfs(j);
                  
                // We put the details of
                // component in final output
                // array
                a.add(j);
                b.add(w);
                c.add(ans);
            }
              
        System.out.println(a.size());
          
        for (int j = 0; j < a.size(); ++j)
            System.out.println(a.get(j) + " " 
                + b.get(j) + " " + c.get(j));
    }
  
    // main function
    public static void main(String args[])
    {
        n = 9;
        p = 6;
          
        // set the value of the araray 
        // to zero
        for(int i = 0; i < 1100; i++)
            rd[i] = cd[i] = wt[i] = 0;
          
        int arr[][] = { { 7, 4, 98 },
                        { 5, 9, 72 },
                        { 4, 6, 10 },
                        { 2, 8, 22 },
                        { 9, 7, 17 },
                        { 3, 1, 66 } };
        solve(arr);
    }
}
  
// This code is contributed by Arnab Kundu


Python3
# Python3 program to find efficient
# solution for the network
  
# number of houses and number
# of pipes
n = 0
p = 0
  
# Array rd stores the 
# ending vertex of pipe
rd = [0]*1100
  
# Array wd stores the value 
# of diameters between two pipes
wt = [0]*1100
  
# Array cd stores the 
# starting end of pipe
cd = [0]*1100
  
# List a, b, c are used
# to store the final output
a = []
b = []
c = []
  
ans = 0
  
def dfs(w):
    global ans
    if (cd[w] == 0):
        return w
    if (wt[w] < ans):
        ans = wt[w]
    return dfs(cd[w])
  
# Function performing calculations.
def solve(arr):
    global ans
    i = 0
    while (i < p):
        q = arr[i][0]
        h = arr[i][1]
        t = arr[i][2]
          
        cd[q] = h
        wt[q] = t
        rd[h] = q
        i += 1
    a = []
    b = []
    c = []
      
    '''If a pipe has no ending vertex 
    but has starting vertex i.e is 
    an outgoing pipe then we need 
    to start DFS with this vertex.'''
    for j in range(1, n + 1):
        if (rd[j] == 0 and cd[j]):
              
            ans = 1000000000
            w = dfs(j)
              
            # We put the details of component
            # in final output array
            a.append(j)
            b.append(w) 
            c.append(ans)
    print(len(a))
    for j in range(len(a)):
        print(a[j], b[j], c[j])
  
# Driver function
n = 9
p = 6
  
arr = [[7, 4, 98], [5, 9, 72], [4, 6, 10 ], 
        [2, 8, 22 ], [9, 7, 17], [3, 1, 66]]
  
solve(arr)
  
# This code is contributed by shubhamsingh10


C#
// C# program to find efficient 
// solution for the network 
using System;
using System.Linq;
using System.Collections.Generic; 
  
class GFG 
{ 
      
    // number of houses and number 
    // of pipes 
    static int n, p; 
  
    // Array rd stores the 
    // ending vertex of pipe 
    static int []rd = new int[1100]; 
  
    // Array wd stores the value 
    // of diameters between two pipes 
    static int []wt = new int[1100]; 
  
    // Array cd stores the 
    // starting end of pipe 
    static int []cd = new int[1100]; 
  
    // arraylist a, b, c are used 
    // to store the final output 
    static List  a = 
            new List (); 
                  
    static List  b = 
            new List (); 
                  
    static List  c = 
            new List (); 
      
    static int ans; 
      
    static int dfs(int w) 
    { 
        if (cd[w] == 0) 
            return w; 
        if (wt[w] < ans) 
            ans = wt[w]; 
              
        return dfs(cd[w]); 
    } 
  
    // Function to perform calculations. 
    static void solve(int [,]arr) 
    { 
        int i = 0; 
      
        while (i < p) 
        { 
              
            int q = arr[i,0]; 
            int h = arr[i,1]; 
            int t = arr[i,2]; 
              
            cd[q] = h; 
            wt[q] = t; 
            rd[h] = q; 
            i++; 
        } 
          
        a = new List (); 
        b = new List (); 
        c = new List (); 
          
        for (int j = 1; j <= n; ++j) 
          
            /*If a pipe has no ending vertex 
            but has starting vertex i.e is 
            an outgoing pipe then we need 
            to start DFS with this vertex.*/
            if (rd[j] == 0 && cd[j] > 0) 
            { 
                ans = 1000000000; 
                int w = dfs(j); 
                  
                // We put the details of 
                // component in final output 
                // array 
                a.Add(j); 
                b.Add(w); 
                c.Add(ans); 
            } 
              
        Console.WriteLine(a.Count); 
          
        for (int j = 0; j < a.Count; ++j) 
            Console.WriteLine(a[j] + " "
                + b[j] + " " + c[j]); 
    } 
  
    // Driver code 
    public static void Main(String []args) 
    { 
        n = 9; 
        p = 6; 
          
        // set the value of the araray 
        // to zero 
        for(int i = 0; i < 1100; i++) 
            rd[i] = cd[i] = wt[i] = 0; 
          
        int [,]arr = { { 7, 4, 98 }, 
                        { 5, 9, 72 }, 
                        { 4, 6, 10 }, 
                        { 2, 8, 22 }, 
                        { 9, 7, 17 }, 
                        { 3, 1, 66 } }; 
        solve(arr); 
    } 
} 
  
// This code has been contributed by 29AjayKumar


输出:

3
2 8 22
3 1 66
5 6 10