# Minimum time to burn a Tree starting from a Leaf node

Given a binary tree and a leaf node from this tree. It is known that in 1s all nodes connected to a given node (left child, right child and parent) get burned in 1 second. Then all the nodes which are connected through one intermediate get burned in 2 seconds, and so on. The task is to find the minimum time required to burn the complete binary tree.

Examples:

```Input :
1
/       \
2          3
/  \          \
4    5          6
/   \         \
7     8         9
\
10
Leaf = 8
Output : 7
Initially 8 is set to fire at 0th sec.
1
/       \
2          3
/  \          \
4    5          6
/   \         \
7     F         9
\
10
After 1s: 5 is set to fire.
1
/       \
2          3
/  \          \
4    F          6
/   \         \
7     F         9
\
10
After 2s: 2, 7 are set to fire.
1
/       \
F          3
/  \          \
4    F          6
/   \         \
F     F         9
\
10
After 3s: 4, 1 are set to fire.
F
/       \
F          3
/  \          \
F    F          6
/   \         \
F     F         9
\
10
After 4s: 3 is set to fire.
F
/       \
F          F
/  \          \
F    F          6
/   \         \
F     F         9
\
10
After 5s: 6 is set to fire.
F
/       \
F          F
/  \          \
F    F          F
/   \         \
F     F         9
\
10
After 6s: 9 is set to fire.
F
/       \
F          F
/  \          \
F    F          F
/   \         \
F     F         F
\
10
After 7s: 10 is set to fire.
F
/       \
F          F
/  \          \
F    F          F
/   \         \
F     F         F
\
F
It takes 7s to burn the complete tree.
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

The idea is to store additional information for every node:

• Depth of left subtree.
• Depth of right subtree.
• The time required for the fire to reach the current node starting from the first leaf node burned.
• A boolean variable to check if the initial burnt node is in the tree rooted under current node.

Before moving ahead with the approach let’s take a look at the tree below:

```              1
/      \
2            3
/   \         /
4     5       6
/     / \
8     9   10
/
11
```

In the above tree, if we set the leaf node 11 at fire.

1. In 1s, the fire will reach node 9.
2. In 2s, the fire will reach node 5.
3. In 3rd second, the fire will reach node 2 and 10. Here comes an observation:
• In 2s fire reached node 5. For node 5, the initial burned leaf is in it’s left subtree, so the time taken to burn right subtree will be the height of the right subtree which is 1. Therefore, fire reaches to node 10 in (2+1) = 3s.
• Again, for the node 2. Fire reached to node 2 in 3s from right subtree. Therefore, time taken to burn left subtree will be it’s height.

So the solution is to apply recursion and for every node calculate the below-required values:

• Left Depth.
• Right Depth.
• The time required for fire to reach the current node.
• Is the current subtree conatins initial burnt leaf node.

So, for the minimum time required to burn any subtree will be:

The time required for fire to reach the root node from initial burnt leaf + depth of the opposite side

Therefore, to find time required to burn the complete tree, we need to calculate the above value for every node, and take maximum of that value.

ans = max(ans, (time required for fire to reach current node + depth of other subtree))

Below is the implementation of the above approach:

## C++

 `// C++ program to find minimum time required ` `// to burn the binary tree completely ` ` `  `#include ` `using` `namespace` `std; ` ` `  `// Tree Node ` `struct` `Node { ` `    ``int` `data; ` `    ``Node* left; ` `    ``Node* right; ` ` `  `    ``Node() ` `    ``{ ` `        ``left = NULL; ` `        ``right = NULL; ` `    ``} ` `}; ` ` `  `// Utility function to create a new Node ` `Node* newNode(``int` `val) ` `{ ` `    ``Node* temp = ``new` `Node; ` ` `  `    ``temp->data = val; ` ` `  `    ``return` `temp; ` `} ` ` `  `/*   ` `    ``***********ADDITIONAL INFO************* ` `    ``lDepth - maximum height of left subtree ` `    ``rDepth - maximum height of right subtree ` `    ``contains - stores true if tree rooted at current node  ` `               ``contains the first burnt node ` `    ``time - time to reach fire from the initally burnt leaf  ` `           ``node to this node ` `*/` `struct` `Info { ` `    ``int` `lDepth; ` `    ``int` `rDepth; ` `    ``bool` `contains; ` ` `  `    ``int` `time``; ` ` `  `    ``Info() ` `    ``{ ` `        ``lDepth = rDepth = 0; ` `        ``contains = ``false``; ` ` `  `        ``time` `= -1; ` `    ``} ` `}; ` ` `  `/*   ` `    ``Function to calculate time required to burn  ` `    ``tree completely ` `     `  `    ``node - address of current node ` `    ``info - extra information about current node ` `    ``target - node that is fired ` `    ``res - stores the result ` `*/` `Info calcTime(Node* node, Info& info, ``int` `target, ``int``& res) ` `{ ` ` `  `    ``// Base case: if root is null ` `    ``if` `(node == NULL) { ` `        ``return` `info; ` `    ``} ` ` `  `    ``// If current node is leaf ` `    ``if` `(node->left == NULL && node->right == NULL) { ` ` `  `        ``// If current node is the first burnt node ` `        ``if` `(node->data == target) { ` `            ``info.contains = ``true``; ` `            ``info.``time` `= 0; ` `        ``} ` `        ``return` `info; ` `    ``} ` ` `  `    ``// Information about left child of root ` `    ``Info leftInfo; ` `    ``calcTime(node->left, leftInfo, target, res); ` ` `  `    ``// Information about right child of root ` `    ``Info rightInfo; ` `    ``calcTime(node->right, rightInfo, target, res); ` ` `  `    ``// If left subtree contains the fired node then ` `    ``// time required to reach fire to current node ` `    ``// will be (1 + time required for left child) ` `    ``info.``time` `= (node->left && leftInfo.contains) ? (leftInfo.``time` `+ 1) : -1; ` ` `  `    ``// If right subtree contains the fired node then ` `    ``// time required to reach fire to current node ` `    ``// will be (1 + time required for right child) ` `    ``if` `(info.``time` `== -1) ` `        ``info.``time` `= (node->right && rightInfo.contains) ? (rightInfo.``time` `+ 1) : -1; ` ` `  `    ``// Storing(true or false) if the tree rooted at ` `    ``// current node contains the fired node ` `    ``info.contains = ((node->left && leftInfo.contains) || (node->right && rightInfo.contains)); ` ` `  `    ``// Calculate the maximum depth of left subtree ` `    ``info.lDepth = !(node->left) ? 0 : (1 + max(leftInfo.lDepth, leftInfo.rDepth)); ` ` `  `    ``// Calculate the maximum depth of right subtree ` `    ``info.rDepth = !(node->right) ? 0 : (1 + max(rightInfo.lDepth, rightInfo.rDepth)); ` ` `  `    ``// Calculating answer ` `    ``if` `(info.contains) { ` `        ``// If left subtree exists and ` `        ``// it contains the fired node ` `        ``if` `(node->left && leftInfo.contains) { ` `            ``// calculate result ` `            ``res = max(res, info.``time` `+ info.rDepth); ` `        ``} ` ` `  `        ``// If right subtree exists and it ` `        ``// contains the fired node ` `        ``if` `(node->right && rightInfo.contains) { ` `            ``// calculate result ` `            ``res = max(res, info.``time` `+ info.lDepth); ` `        ``} ` `    ``} ` `} ` ` `  `// Driver function to calculate minimum ` `// time required ` `int` `minTime(Node* root, ``int` `target) ` `{ ` `    ``int` `res = 0; ` `    ``Info info; ` ` `  `    ``calcTime(root, info, target, res); ` ` `  `    ``return` `res; ` `} ` ` `  `// Driver Code ` `int` `main() ` `{ ` `    ``Node* root = newNode(1); ` `    ``root->left = newNode(2); ` `    ``root->right = newNode(3); ` `    ``root->left->left = newNode(4); ` `    ``root->left->right = newNode(5); ` `    ``root->right->left = newNode(6); ` `    ``root->left->left->left = newNode(8); ` `    ``root->left->right->left = newNode(9); ` `    ``root->left->right->right = newNode(10); ` `    ``root->left->right->left->left = newNode(11); ` ` `  `    ``// target node is 8 ` `    ``int` `target = 11; ` ` `  `    ``cout << minTime(root, target); ` ` `  `    ``return` `0; ` `} `

## Java

 `// Java program to find minimum time required ` `// to burn the binary tree completely ` ` `  `public` `class` `GFG { ` ` `  `    ``// Tree Node ` `    ``static` `class` `Node { ` `        ``int` `data; ` `        ``Node left, right; ` ` `  `        ``Node(``int` `data) ` `        ``{ ` `            ``this``.data = data; ` `            ``this``.left = ``null``; ` `            ``this``.right = ``null``; ` `        ``} ` `    ``} ` ` `  `    ``/*  ` `        ``***********ADDITIONAL INFO************* ` `        ``lDepth - maximum height of left subtree ` `        ``rDepth - maximum height of right subtree ` `        ``contains - stores true if tree rooted at current node  ` `                ``contains the first burnt node ` `        ``time - time to reach fire from the initally burnt leaf  ` `            ``node to this node ` `    ``*/` `    ``static` `class` `Data { ` `        ``int` `leftDepth, rightDepth, time; ` `        ``boolean` `contains; ` ` `  `        ``Data() ` `        ``{ ` `            ``contains = ``false``; ` `            ``leftDepth = rightDepth = ``0``; ` `            ``time = -``1``; ` `        ``} ` `    ``} ` ` `  `    ``/*  ` `        ``Function to calculate time required to burn  ` `        ``tree completely ` `         `  `        ``node - address of current node ` `        ``info - extra information about current node ` `        ``target - node that is fired ` `        ``res - stores the result ` `    ``*/` `    ``public` `static` `void` `getResult(Node node, Data data, ``int` `target) ` `    ``{ ` ` `  `        ``// Base case: if root is null ` `        ``if` `(node == ``null``) { ` `            ``return``; ` `        ``} ` ` `  `        ``// If current node is leaf ` `        ``if` `(node.left == ``null` `&& node.right == ``null``) { ` ` `  `            ``// If current node is the first burnt node ` `            ``if` `(node.data == target) { ` `                ``data.contains = ``true``; ` `                ``data.time = ``0``; ` `            ``} ` `            ``return``; ` `        ``} ` ` `  `        ``// Information about left child ` `        ``Data leftData = ``new` `Data(); ` `        ``getResult(node.left, leftData, target); ` ` `  `        ``// Information about right child ` `        ``Data rightData = ``new` `Data(); ` `        ``getResult(node.right, rightData, target); ` ` `  `        ``// If left subtree contains the fired node then ` `        ``// time required to reach fire to current node ` `        ``// will be (1 + time required for left child) ` `        ``data.time = (leftData.contains) ? (leftData.time + ``1``) : -``1``; ` ` `  `        ``// If right subtree contains the fired node then ` `        ``// time required to reach fire to current node ` `        ``// will be (1 + time required for right child) ` `        ``if` `(data.time == -``1``) ` `            ``data.time = (rightData.contains) ? (rightData.time + ``1``) : -``1``; ` ` `  `        ``// Storing(true or false) if the tree rooted at ` `        ``// current node contains the fired node ` `        ``data.contains = (leftData.contains || rightData.contains); ` ` `  `        ``// Calculate the maximum depth of left subtree ` `        ``data.leftDepth = (node.left == ``null``) ? ``0` `: (``1` `+ Math.max(leftData.leftDepth, leftData.rightDepth)); ` ` `  `        ``// Calculate the maximum depth of right subtree ` `        ``data.rightDepth = (node.right == ``null``) ? ``0` `: (``1` `+ Math.max(rightData.leftDepth, rightData.rightDepth)); ` ` `  `        ``// Calculating answer ` `        ``if` `(data.contains) { ` ` `  `            ``// If left subtree exists and ` `            ``// it contains the fired node ` `            ``if` `(leftData.contains) { ` ` `  `                ``// calculate result ` `                ``res = Math.max(res, data.time + data.rightDepth); ` `            ``} ` ` `  `            ``// If right subtree exists and it ` `            ``// contains the fired node ` `            ``if` `(rightData.contains) { ` ` `  `                ``// calculate result ` `                ``res = Math.max(res, data.time + data.leftDepth); ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``// To store the result ` `    ``public` `static` `int` `res; ` ` `  `    ``// Driver Code ` `    ``public` `static` `void` `main(String args[]) ` `    ``{ ` ` `  `        ``Node root = ``new` `Node(``1``); ` `        ``root.left = ``new` `Node(``2``); ` `        ``root.right = ``new` `Node(``3``); ` `        ``root.left.left = ``new` `Node(``4``); ` `        ``root.left.right = ``new` `Node(``5``); ` `        ``root.right.left = ``new` `Node(``6``); ` `        ``root.left.left.left = ``new` `Node(``8``); ` `        ``root.left.right.left = ``new` `Node(``9``); ` `        ``root.left.right.right = ``new` `Node(``10``); ` `        ``root.left.right.left.left = ``new` `Node(``11``); ` ` `  `        ``int` `target = ``11``; ` ` `  `        ``res = ``0``; ` `        ``getResult(root, ``new` `Data(), target); ` `        ``System.out.println(res); ` `    ``} ` `} `

## C#

 `// C# program to find minimum time required ` `// to burn the binary tree completely ` `using` `System; ` ` `  `class` `GFG  ` `{ ` ` `  `    ``// Tree Node ` `    ``class` `Node  ` `    ``{ ` `        ``public` `int` `data; ` `        ``public` `Node left, right; ` ` `  `        ``public` `Node(``int` `data) ` `        ``{ ` `            ``this``.data = data; ` `            ``this``.left = ``null``; ` `            ``this``.right = ``null``; ` `        ``} ` `    ``} ` ` `  `    ``/*  ` `        ``***********ADDITIONAL INFO************* ` `        ``lDepth - maximum height of left subtree ` `        ``rDepth - maximum height of right subtree ` `        ``contains - stores true if tree rooted at current node  ` `                ``contains the first burnt node ` `        ``time - time to reach fire from the initally burnt leaf  ` `            ``node to this node ` `    ``*/` `    ``class` `Data  ` `    ``{ ` `        ``public` `int` `leftDepth, rightDepth, time; ` `        ``public` `bool` `contains; ` ` `  `        ``public` `Data() ` `        ``{ ` `            ``contains = ``false``; ` `            ``leftDepth = rightDepth = 0; ` `            ``time = -1; ` `        ``} ` `    ``} ` ` `  `    ``/*  ` `        ``Function to calculate time required to burn  ` `        ``tree completely ` `         `  `        ``node - address of current node ` `        ``info - extra information about current node ` `        ``target - node that is fired ` `        ``res - stores the result ` `    ``*/` `    ``static` `void` `getResult(Node node, Data data,  ` `                            ``int` `target) ` `    ``{ ` ` `  `        ``// Base case: if root is null ` `        ``if` `(node == ``null``)  ` `        ``{ ` `            ``return``; ` `        ``} ` ` `  `        ``// If current node is leaf ` `        ``if` `(node.left == ``null` `&& ` `            ``node.right == ``null``)  ` `        ``{ ` ` `  `            ``// If current node is the first burnt node ` `            ``if` `(node.data == target) ` `            ``{ ` `                ``data.contains = ``true``; ` `                ``data.time = 0; ` `            ``} ` `            ``return``; ` `        ``} ` ` `  `        ``// Information about left child ` `        ``Data leftData = ``new` `Data(); ` `        ``getResult(node.left, leftData, target); ` ` `  `        ``// Information about right child ` `        ``Data rightData = ``new` `Data(); ` `        ``getResult(node.right, rightData, target); ` ` `  `        ``// If left subtree contains the fired node then ` `        ``// time required to reach fire to current node ` `        ``// will be (1 + time required for left child) ` `        ``data.time = (leftData.contains) ?  ` `                    ``(leftData.time + 1) : -1; ` ` `  `        ``// If right subtree contains the fired node then ` `        ``// time required to reach fire to current node ` `        ``// will be (1 + time required for right child) ` `        ``if` `(data.time == -1) ` `            ``data.time = (rightData.contains) ?  ` `                        ``(rightData.time + 1) : -1; ` ` `  `        ``// Storing(true or false) if the tree rooted at ` `        ``// current node contains the fired node ` `        ``data.contains = (leftData.contains ||  ` `                        ``rightData.contains); ` ` `  `        ``// Calculate the maximum depth of left subtree ` `        ``data.leftDepth = (node.left == ``null``) ?  ` `                          ``0 : (1 + Math.Max( ` `                          ``leftData.leftDepth, ` `                          ``leftData.rightDepth)); ` ` `  `        ``// Calculate the maximum depth of right subtree ` `        ``data.rightDepth = (node.right == ``null``) ?  ` `                           ``0 : (1 + Math.Max( ` `                          ``rightData.leftDepth,  ` `                          ``rightData.rightDepth)); ` ` `  `        ``// Calculating answer ` `        ``if` `(data.contains)  ` `        ``{ ` ` `  `            ``// If left subtree exists and ` `            ``// it contains the fired node ` `            ``if` `(leftData.contains)  ` `            ``{ ` ` `  `                ``// calculate result ` `                ``res = Math.Max(res, data.time + ` `                                ``data.rightDepth); ` `            ``} ` ` `  `            ``// If right subtree exists and it ` `            ``// contains the fired node ` `            ``if` `(rightData.contains) ` `            ``{ ` ` `  `                ``// calculate result ` `                ``res = Math.Max(res, data.time +  ` `                                ``data.leftDepth); ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``// To store the result ` `    ``public` `static` `int` `res; ` ` `  `    ``// Driver Code ` `    ``public` `static` `void` `Main(String []args) ` `    ``{ ` ` `  `        ``Node root = ``new` `Node(1); ` `        ``root.left = ``new` `Node(2); ` `        ``root.right = ``new` `Node(3); ` `        ``root.left.left = ``new` `Node(4); ` `        ``root.left.right = ``new` `Node(5); ` `        ``root.right.left = ``new` `Node(6); ` `        ``root.left.left.left = ``new` `Node(8); ` `        ``root.left.right.left = ``new` `Node(9); ` `        ``root.left.right.right = ``new` `Node(10); ` `        ``root.left.right.left.left = ``new` `Node(11); ` ` `  `        ``int` `target = 11; ` ` `  `        ``res = 0; ` `        ``getResult(root, ``new` `Data(), target); ` `        ``Console.WriteLine(res); ` `    ``} ` `} ` ` `  `// This code is contributed by PrinciRaj1992 `

Output:

```6
```

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Improved By : princiraj1992

Article Tags :
Practice Tags :

11

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.