Water Connection Problem - GeeksforGeeks

25 Apr, 2022
Every house in the colony has at most one pipe going into it and at most one pipe going out of it. Tanks and taps are to be installed in a manner such that every house with one outgoing pipe but no incoming pipe gets a tank installed on its roof and every house with only an incoming pipe and no outgoing pipe gets a tap.
Given two integers n and p denoting the number of houses and the number of pipes. The connections of pipe among the houses contain three input values: a_i, b_i, d_i denoting the pipe of diameter d_i from house a_i to house b_i, find out the efficient solution for the network. 
The output will contain the number of pairs of tanks and taps t installed in first line and the next t lines contain three integers: house number of tank, house number of tap and the minimum diameter of pipe between them.
Examples:  
Input:  4 2        1 2 60        3 4 50Output: 2        1 2 60        3 4 50Explanation:Connected components are: 1->2 and 3->4Therefore, 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 66Output: 3        2 8 22        3 1 66        5 6 10Explanation: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
Approach: 
Perform DFS from appropriate houses to find all different connected components. The number of different connected components is our answer t. 
The next t lines of the output are the beginning of the connected component, end of the connected component and the minimum diameter from the start to the end of the connected component in each line. 
Since, tanks can be installed only on the houses having outgoing pipe and no incoming pipe, therefore these are appropriate houses to start DFS from i.e. perform DFS from such unvisited houses.
Below is the implementation of above approach: 
C++
Java
Python3
C#
Javascript
// C++ program to find efficient// solution for the network#include <cstring> // For memset#include <iostream>#include <vector> using std::cin;using std::cout;using std::endl;using std::memset;using std::vector;// number of houses and number// of pipesint number_of_houses, number_of_pipes; // Array rd stores the// ending vertex of pipeint ending_vertex_of_pipes[1100]; // Array wd stores the value// of diameters between two pipesint diameter_between_two_pipes[1100]; // Array cd stores the// starting end of pipeint starting_vertex_of_pipes[1100]; // Vector a, b, c are used// to store the final outputvector<int> a;vector<int> b;vector<int> c; int ans; int dfs(int w){    if (starting_vertex_of_pipes[w] == 0)        return w;    if (diameter_between_two_pipes[w] < ans)        ans = diameter_between_two_pipes[w];    return dfs(starting_vertex_of_pipes[w]);} // Function performing calculations.void solve(int arr[][3]){    for (int i = 0; i < number_of_pipes; ++i) {         int house_1 = arr[i][0], house_2 = arr[i][1],            pipe_diameter = arr[i][2];         starting_vertex_of_pipes[house_1] = house_2;        diameter_between_two_pipes[house_1] = pipe_diameter;        ending_vertex_of_pipes[house_2] = house_1;    }     a.clear();    b.clear();    c.clear();     for (int j = 1; j <= number_of_houses; ++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 (ending_vertex_of_pipes[j] == 0            && starting_vertex_of_pipes[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 functionint main(){    number_of_houses = 9, number_of_pipes = 6;     memset(ending_vertex_of_pipes, 0,           sizeof(ending_vertex_of_pipes));    memset(starting_vertex_of_pipes, 0,           sizeof(starting_vertex_of_pipes));    memset(diameter_between_two_pipes, 0,           sizeof(diameter_between_two_pipes));     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 program to find efficient// solution for the networkimport java.util.*; class GFG {     // number of houses and number    // of pipes    static int number_of_houses, number_of_pipes;     // Array rd stores the    // ending vertex of pipe    static int ending_vertex_of_pipes[] = new int[1100];     // Array wd stores the value    // of diameters between two pipes    static int diameter_of_pipes[] = new int[1100];     // Array cd stores the    // starting end of pipe    static int starting_vertex_of_pipes[] = new int[1100];     // arraylist a, b, c are used    // to store the final output    static List<Integer> a = new ArrayList<Integer>();     static List<Integer> b = new ArrayList<Integer>();     static List<Integer> c = new ArrayList<Integer>();     static int ans;     static int dfs(int w)    {        if (starting_vertex_of_pipes[w] == 0)            return w;        if (diameter_of_pipes[w] < ans)            ans = diameter_of_pipes[w];         return dfs(starting_vertex_of_pipes[w]);    }     // Function to perform calculations.    static void solve(int arr[][])    {        int i = 0;         while (i < number_of_pipes) {             int q = arr[i][0];            int h = arr[i][1];            int t = arr[i][2];             starting_vertex_of_pipes[q] = h;            diameter_of_pipes[q] = t;            ending_vertex_of_pipes[h] = q;            i++;        }         a = new ArrayList<Integer>();        b = new ArrayList<Integer>();        c = new ArrayList<Integer>();         for (int j = 1; j <= number_of_houses; ++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 (ending_vertex_of_pipes[j] == 0                && starting_vertex_of_pipes[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[])    {        number_of_houses = 9;        number_of_pipes = 6;         // set the value of the array        // to zero        for (int i = 0; i < 1100; i++)            ending_vertex_of_pipes[i]                = starting_vertex_of_pipes[i]                = diameter_of_pipes[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 program to find efficient# solution for the network # number of houses and number# of pipesn = 0p = 0 # Array rd stores the# ending vertex of piperd = [0]*1100 # Array wd stores the value# of diameters between two pipeswt = [0]*1100 # Array cd stores the# starting end of pipecd = [0]*1100 # List a, b, c are used# to store the final outputa = []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 functionn = 9p = 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# program to find efficient// solution for the networkusing 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 <int> a =            new List <int>();                     static List <int> b =            new List <int>();                     static List <int> c =            new List <int>();         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 <int>();        b = new List <int>();        c = new List <int>();                 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 array        // 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
<script> // JavaScript program to find efficient// solution for the network // number of houses and number    // of pipeslet n, p; // Array rd stores the    // ending vertex of pipelet rd=new Array(1100); // Array wd stores the value    // of diameters between two pipeslet wt=new Array(1100); // Array cd stores the    // starting end of pipelet cd=new Array(1100); // arraylist a, b, c are used    // to store the final outputlet a=[]; let b=[]; let c=[]; let ans; function dfs(w){    if (cd[w] == 0)            return w;        if (wt[w] < ans)            ans = wt[w];                       return dfs(cd[w]);} // Function to perform calculations.function solve(arr){    let i = 0;               while (i < p)        {                           let q = arr[i][0];            let h = arr[i][1];            let t = arr[i][2];                           cd[q] = h;            wt[q] = t;            rd[h] = q;            i++;        }                   a=[];        b=[];        c=[];                   for (let 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;                let w = dfs(j);                                   // We put the details of                // component in final output                // array                a.push(j);                b.push(w);                c.push(ans);            }                       document.write(a.length+"<br>");                   for (let j = 0; j < a.length; ++j)            document.write(a[j] + " "                + b[j] + " " + c[j]+"<br>");} // main functionn = 9;p = 6; // set the value of the array// to zerofor(let i = 0; i < 1100; i++)    rd[i] = cd[i] = wt[i] = 0; let 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 avanitrachhadiya2155 </script>
3
2 8 22
3 1 66
5 6 10

andrew1234
R0SHANRK_1995
29AjayKumar
SHUBHAMSINGH10
avanitrachhadiya2155
nnr223442
GaurishGangwar
RishabhPrabhu
DFS
Competitive Programming
Graph
Greedy
Greedy
DFS
Graph
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Prefix Sum Array - Implementation and Applications in Competitive Programming
Ordered Set and GNU C++ PBDS
Modulo 10^9+7 (1000000007)
Bits manipulation (Important tactics)
7 Best Coding Challenge Websites in 2020
Breadth First Search or BFS for a Graph
Dijkstra's shortest path algorithm | Greedy Algo-7
Depth First Search or DFS for a Graph
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2