# Minimize water to fill all tanks connected by given circuit

• Last Updated : 28 Sep, 2022

Given N tanks connected like a tree, the connections between them in an array Edge[][], and the capacity of each tank in the array cap[], the task is to find the minimum amount of water required to pour into the given tank such that all the tanks are filled.

Note: When a tank is filled, the remaining amount of water is equally distributed among the other tanks which are connected to it except the one which is the source for this tank. Also, the maximum water available is 1018.

Examples:

Input: N = 4, S = 1, Edges = [[1, 2], [1, 3], [2, 4]], Cap = [1, 1, 1, 1]
Output: 5
Explanation: Initially, 5 unit of water is poured into
tank 1. 2 unit of it flows to tank 2 and
2 unit of it flows into tank 3. From 2
unit of water in tank 2, 1 unit flows into
tank 4 and 1 unit from tank 3 are wasted. Example 1

Input: N = 3 and S = 2, Edges = [[1, 2], [2, 3]], Cap = [1, 1, 1]
Output: 3

Approach: This problem can be solved using Depth First Search based on the following idea:

For any depth, the amount of water that needs to flow in every tank as the same as the maximum requirement for a single tank. If this is followed in bottom-up manner we will get the minimum required water in the source.

Follow the steps mentioned below to implement the idea:

• Create an adjacency list for the tree using the given edges.
• Create a visited array to store if a node has been visited or not.
• Now start depth-first traversal from the given start node.
• Add capacity of the current node in answer. Add the maximum cost of dfs in adjacent nodes multiplied by all connected nodes except the parent node.

dfs[node] = cap[node] + (number of child except parent node) * max(dfs(child))

• If dfs(node) is greater than 1018 or dfs(child) is -1 then  return -1.

Below is the implementation of the above approach:

## C++

 `// C++ code to implement the approach` `#include ``using` `namespace` `std;` `const` `long` `long` `rmx = 1e18;` `// Function to implement DFS``long` `long` `dfs(``int` `node, ``int` `num, ``int` `cap[],``              ``vector >& adj,``              ``vector<``int``>& vis,``              ``int` `start)``{``    ``// Mark the current node as visited``    ``vis[node] = 1;` `    ``// Initialize answer as capacity required``    ``// by this node(tank)``    ``long` `long` `ans = cap[node - 1];` `    ``// mx to store the max water required``    ``// by adjacent node``    ``long` `long` `mx = 0;` `    ``// DFS traversal``    ``for` `(``auto` `child : adj[node]) {``        ``if` `(!vis[child]) {``            ``long` `long` `cdfs``                ``= dfs(child, num, cap, adj,``                      ``vis, start);``            ``if` `(cdfs == -1) {``                ``mx = -1;``                ``break``;``            ``}``            ``mx = max(mx, cdfs);``        ``}``    ``}``    ``if` `(mx == -1)``        ``return` `-1;``    ``if` `(node == start)``        ``ans += adj[node].size() * mx;``    ``else``        ``ans += (adj[node].size() - 1) * mx;` `    ``if` `(ans > rmx)``        ``return` `-1;``    ``return` `ans;``}` `// Function to find the minimum amount of water``long` `long` `minimum_amount(vector >& Edges,``                         ``int` `num, ``int` `start, ``int``* cap)``{` `    ``// Adjacency list to store graph``    ``vector > adj(num + 1);` `    ``// vis array to mark visited nodes``    ``vector<``int``> vis(num + 1);``    ``for` `(``int` `i = 0; i < Edges.size(); i++) {``        ``adj[Edges[i]].push_back(Edges[i]);``        ``adj[Edges[i]].push_back(Edges[i]);``    ``}``    ``return` `dfs(start, num, cap, adj, vis, start);``}` `// Driver code``int` `main()``{``    ``int` `num = 4, start = 1;``    ``int` `cap[] = { 1, 1, 1, 1 };``    ``vector > Edges``        ``= { { 1, 2 }, { 1, 3 }, { 2, 4 } };` `    ``// Function call``    ``cout << minimum_amount(Edges, num, start, cap);` `    ``return` `0;``}`

## Java

 `// Java code to implement the approach``import` `java.util.*;` `class` `GFG{` `static` `long` `rmx = (``long``) 1e18;` `// Function to implement DFS``static` `long` `dfs(``int` `node, ``int` `num, ``int` `cap[],``        ``Vector [] adj,``        ``int` `[] vis,``              ``int` `start)``{``    ``// Mark the current node as visited``    ``vis[node]=``1``;` `    ``// Initialize answer as capacity required``    ``// by this node(tank)``    ``long` `ans = cap[node - ``1``];` `    ``// mx to store the max water required``    ``// by adjacent node``    ``long` `mx = ``0``;` `    ``// DFS traversal``    ``for` `(``int` `child : adj[node]) {``        ``if` `(vis[child]!=``1``) {``            ``long` `cdfs``                ``= dfs(child, num, cap, adj,``                      ``vis, start);``            ``if` `(cdfs == -``1``) {``                ``mx = -``1``;``                ``break``;``            ``}``            ``mx = Math.max(mx, cdfs);``        ``}``    ``}``    ``if` `(mx == -``1``)``        ``return` `-``1``;``    ``if` `(node == start)``        ``ans += adj[node].size() * mx;``    ``else``        ``ans += (adj[node].size() - ``1``) * mx;` `    ``if` `(ans > rmx)``        ``return` `-``1``;``    ``return` `ans;``}` `// Function to find the minimum amount of water``static` `long` `minimum_amount(``int``[][]  Edges,``                         ``int` `num, ``int` `start, ``int` `[]cap)``{` `    ``// Adjacency list to store graph``    ``Vector []adj  = ``new` `Vector[num + ``1``];``    ``for``(``int` `i = ``0``; i < num + ``1``; i++)``        ``adj[i] = ``new` `Vector();``    ``// vis array to mark visited nodes``    ``int` `[]vis  = ``new` `int``[num + ``1``];` `    ``for` `(``int` `i = ``0``; i < Edges.length; i++) {``        ``adj[Edges[i][``0``]].add(Edges[i][``1``]);``        ``adj[Edges[i][``1``]].add(Edges[i][``0``]);``    ``}``    ``return` `dfs(start, num, cap, adj, vis, start);``}` `// Driver code``public` `static` `void` `main(String[] args)``{``    ``int` `num = ``4``, start = ``1``;``    ``int` `cap[] = { ``1``, ``1``, ``1``, ``1` `};``    ``int``[][] Edges``        ``= { { ``1``, ``2` `}, { ``1``, ``3` `}, { ``2``, ``4` `} };` `    ``// Function call``    ``System.out.print(minimum_amount(Edges, num, start, cap));` `}``}` `// This code contributed by shikhasingrajput`

## Python3

 `import` `math` `class` `GFG :``    ``rmx ``=` `int``(``1.0E18``)``    ` `    ``# Function to implement DFS``    ``@staticmethod``    ``def`  `dfs( node,  num,  cap,  adj,  vis,  start) :``      ` `        ``# Mark the current node as visited``        ``vis[node] ``=` `1``        ` `        ``# Initialize answer as capacity required``        ``# by this node(tank)``        ``ans ``=` `cap[node ``-` `1``]``        ` `        ``# mx to store the max water required``        ``# by adjacent node``        ``mx ``=` `0``        ``# DFS traversal``        ``for` `child ``in` `adj[node] :``            ``if` `(vis[child] !``=` `1``) :``                ``cdfs ``=` `GFG.dfs(child, num, cap, adj, vis, start)``                ``if` `(cdfs ``=``=` `-``1``) :``                    ``mx ``=` `-``1``                    ``break``                ``mx ``=` `max``(mx,cdfs)``        ``if` `(mx ``=``=` `-``1``) :``            ``return` `-``1``        ``if` `(node ``=``=` `start) :``            ``ans ``+``=` `len``(adj[node]) ``*` `mx``        ``else` `:``            ``ans ``+``=` `(``len``(adj[node]) ``-` `1``) ``*` `mx``        ``if` `(ans > GFG.rmx) :``            ``return` `-``1``        ``return` `ans``      ` `    ``# Function to find the minimum amount of water``    ``@staticmethod``    ``def`  `minimum_amount( Edges,  num,  start,  cap) :``      ` `        ``# Adjacency list to store graph``        ``adj ``=` `[``None``] ``*` `(num ``+` `1``)``        ``i ``=` `0``        ``while` `(i < num ``+` `1``) :``            ``adj[i] ``=`  `[]``            ``i ``+``=` `1``            ` `        ``# vis array to mark visited nodes``        ``vis ``=` `[``0``] ``*` `(num ``+` `1``)``        ``i ``=` `0``        ``while` `(i < ``len``(Edges)) :``            ``adj[Edges[i][``0``]].append(Edges[i][``1``])``            ``adj[Edges[i][``1``]].append(Edges[i][``0``])``            ``i ``+``=` `1``        ``return` `GFG.dfs(start, num, cap, adj, vis, start)``      ` `    ``# Driver code``    ``@staticmethod``    ``def` `main( args) :``        ``num ``=` `4``        ``start ``=` `1``        ``cap ``=` `[``1``, ``1``, ``1``, ``1``]``        ``Edges ``=` `[[``1``, ``2``], [``1``, ``3``], [``2``, ``4``]]``        ` `        ``# Function call``        ``print``(GFG.minimum_amount(Edges, num, start, cap))``    ` `if` `__name__``=``=``"__main__"``:``    ``GFG.main([])``    ` `    ``# This code is contributed by aaditya burujwale.`

## C#

 `// C# code to implement the approach``using` `System;``using` `System.Collections.Generic;` `public` `class` `GFG{` `static` `long` `rmx = (``long``) 1e18;` `// Function to implement DFS``static` `long` `dfs(``int` `node, ``int` `num, ``int` `[]cap,``        ``List<``int``> [] adj,``        ``int` `[] vis,``              ``int` `start)``{``    ``// Mark the current node as visited``    ``vis[node]=1;` `    ``// Initialize answer as capacity required``    ``// by this node(tank)``    ``long` `ans = cap[node - 1];` `    ``// mx to store the max water required``    ``// by adjacent node``    ``long` `mx = 0;` `    ``// DFS traversal``    ``foreach` `(``int` `child ``in` `adj[node]) {``        ``if` `(vis[child]!=1) {``            ``long` `cdfs``                ``= dfs(child, num, cap, adj,``                      ``vis, start);``            ``if` `(cdfs == -1) {``                ``mx = -1;``                ``break``;``            ``}``            ``mx = Math.Max(mx, cdfs);``        ``}``    ``}``    ``if` `(mx == -1)``        ``return` `-1;``    ``if` `(node == start)``        ``ans += adj[node].Count * mx;``    ``else``        ``ans += (adj[node].Count - 1) * mx;` `    ``if` `(ans > rmx)``        ``return` `-1;``    ``return` `ans;``}` `// Function to find the minimum amount of water``static` `long` `minimum_amount(``int``[,]  Edges,``                         ``int` `num, ``int` `start, ``int` `[]cap)``{` `    ``// Adjacency list to store graph``    ``List<``int``> []adj  = ``new` `List<``int``>[num + 1];``    ``for``(``int` `i = 0; i < num + 1; i++)``        ``adj[i] = ``new` `List<``int``>();``    ``// vis array to mark visited nodes``    ``int` `[]vis  = ``new` `int``[num + 1];` `    ``for` `(``int` `i = 0; i < Edges.GetLength(0); i++) {``        ``adj[Edges[i,0]].Add(Edges[i,1]);``        ``adj[Edges[i,1]].Add(Edges[i,0]);``    ``}``    ``return` `dfs(start, num, cap, adj, vis, start);``}` `// Driver code``public` `static` `void` `Main(String[] args)``{``    ``int` `num = 4, start = 1;``    ``int` `[]cap = { 1, 1, 1, 1 };``    ``int``[,] Edges``        ``= { { 1, 2 }, { 1, 3 }, { 2, 4 } };` `    ``// Function call``    ``Console.Write(minimum_amount(Edges, num, start, cap));` `}``}`  `// This code contributed by shikhasingrajput`

## Javascript

 `// JS code to implement the approach``let rmx = 1e18;` `// Function to implement DFS``function` `dfs(node, num, cap, adj, vis, start)``    ` `{``    ``// Mark the current node as visited``    ``vis[node] = 1;` `    ``// Initialize answer as capacity required``    ``// by this node(tank)``    ``let ans = cap[node - 1];` `    ``// mx to store the max water required``    ``// by adjacent node``    ``let mx = 0;` `    ``// DFS traversal``    ``for` `(let child of adj[node]) {``        ``if` `(vis[child]!=1) {``            ``let cdfs``                ``= dfs(child, num, cap, adj,``                      ``vis, start);``            ``if` `(cdfs == -1) {``                ``mx = -1;``                ``break``;``            ``}``            ``mx = Math.max(mx, cdfs);``        ``}``    ``}``    ``if` `(mx == -1)``        ``return` `-1;``    ``if` `(node == start)``        ``ans += adj[node].length * mx;``    ``else``        ``ans += (adj[node].length - 1) * mx;` `    ``if` `(ans > rmx)``        ``return` `-1;``    ``return` `ans;``}` `// Function to find the minimum amount of water``function` `minimum_amount(Edges,  num,   start, cap)``{` `    ``// Adjacency list to store graph``    ``let adj = ``new` `Array(num + 1);``    ``for` `(``var` `i = 0; i <= num; i++)``        ``adj[i] = ``new` `Array();``   ` `    ``// vis array to mark visited nodes``    ``let vis  = ``new` `Array(num + 1);` `    ``for` `(``var` `i = 0; i < Edges.length; i++) {``        ``adj[Edges[i]].push(Edges[i]);``        ``adj[Edges[i]].push(Edges[i]);``    ``}``    ``return` `dfs(start, num, cap, adj, vis, start);``}` `// Driver code``let num = 4, start = 1;``let cap = [ 1, 1, 1, 1 ];``let Edges = [[ 1, 2 ], [ 1, 3 ], [2, 4 ]];` `// Function call``console.log(minimum_amount(Edges, num, start, cap));` `// This code contributed by phasing17`

Output

`5`

Time Complexity: O(V + E), where V is the number of vertices and E is the number of edges.
Auxiliary Space: O(V)

My Personal Notes arrow_drop_up