# Water Connection Problem

• Difficulty Level : Hard
• Last Updated : 29 Sep, 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 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

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++

 `// C++ program to find efficient``// solution for the network``#include // For memset``#include ``#include ` `using` `std::cin;``using` `std::cout;``using` `std::endl;``using` `std::``memset``;``using` `std::vector;``// number of houses and number``// of pipes``int` `number_of_houses, number_of_pipes;` `// Array rd stores the``// ending vertex of pipe``int` `ending_vertex_of_pipes;` `// Array wd stores the value``// of diameters between two pipes``int` `diameter_between_two_pipes;` `// Array cd stores the``// starting end of pipe``int` `starting_vertex_of_pipes;` `// Vector a, b, c are used``// to store the final output``vector<``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[])``{``    ``for` `(``int` `i = 0; i < number_of_pipes; ++i) {` `        ``int` `house_1 = arr[i], house_2 = arr[i],``            ``pipe_diameter = arr[i];` `        ``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 function``int` `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[]``        ``= { { 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` `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 a = ``new` `ArrayList();` `    ``static` `List b = ``new` `ArrayList();` `    ``static` `List c = ``new` `ArrayList();` `    ``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();``        ``b = ``new` `ArrayList();``        ``c = ``new` `ArrayList();` `        ``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

 `# 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``;` `    ``// Array wd stores the value``    ``// of diameters between two pipes``    ``static` `int` `[]wt = ``new` `int``;` `    ``// Array cd stores the``    ``// starting end of pipe``    ``static` `int` `[]cd = ``new` `int``;` `    ``// 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`

## Javascript

 ``

Output

```3
2 8 22
3 1 66
5 6 10```

Time Complexity: O(N) where N is the number of houses.

Auxiliary Space: O(N) because extra space for vector a,b, and c have been used

My Personal Notes arrow_drop_up