Related Articles
Find the minimum dominating set of a Binary tree
• Difficulty Level : Hard
• Last Updated : 21 Dec, 2020

Given a binary tree with N nodes numbered [1, N], the task is to find the size of the smallest Dominating set of that tree.

A set of nodes is said to be a dominating node if every node in the binary tree not present in the set is an immediate child/parent to any node in that set.

Examples:

```Input:
1
/
2
/ \
4   3
/
5
/  \
6    7
/ \    \
8   9   10
Output:  3
Explanation:
Smallest dominating set is {2, 6, 7}

Input:
1
/   \
2     3
/ \   / \
4   5 6   7
/ \   /
8  9  10
Output:  4
Explanation:
One of the smallest
dominating set = {2, 3, 6, 4}```

Approach:
In order to solve this problem we are using a dynamic programming approach by defining the following two states for every node:

• The first state compulsory tells us whether it is compulsory to choose the node in the set or not.
• The second state covered, tells us whether the node’s parent/child is in the set or not.

If it is compulsory to choose the node, we choose it and mark its children as covered. Otherwise, we have an option to choose it or reject it and then update its children as covered or not accordingly. Check the states for every node and find the required size of the set accordingly.
Below code is the implementation of the above approach:

## C++

 `/* C++ program to find the size of the``minimum dominating set of the tree */` `#include ``using` `namespace` `std;` `#define N 1005` `// Definition of a tree node``struct` `Node {``    ``int` `data;``    ``Node *left, *right;``};` `/* Helper function that allocates a``new node */``Node* newNode(``int` `data)``{``    ``Node* node = (Node*)``malloc``(``sizeof``(Node));``    ``node->data = data;``    ``node->left = node->right = NULL;``    ``return` `node;``}` `// DP array to precompute``// and store the results``int` `dp[N][5][5];` `// minDominatingSettion to return the size of``// the minimum dominating set of the array``int` `minDominatingSet(Node* root, ``int` `covered,``                     ``int` `compulsory)``{``    ``// Base case``    ``if` `(!root)``        ``return` `0;` `    ``// Setting the compulsory value if needed``    ``if` `(!root->left and !root->right and !covered)``        ``compulsory = ``true``;` `    ``// Check if the answer is already computed``    ``if` `(dp[root->data][covered][compulsory] != -1)``        ``return` `dp[root->data][covered][compulsory];` `    ``// If it is compulsory to select``    ``// the node``    ``if` `(compulsory) {``        ``// Choose the node and set its children as covered``        ``return` `dp[root->data]``                 ``[covered]``                 ``[compulsory]``               ``= 1``                 ``+ minDominatingSet(``                       ``root->left, 1, 0)``                 ``+ minDominatingSet(``                       ``root->right, 1, 0);``    ``}` `    ``// If it is covered``    ``if` `(covered) {``        ``return` `dp[root->data]``                 ``[covered]``                 ``[compulsory]``               ``= min(``                   ``1``                       ``+ minDominatingSet(``                             ``root->left, 1, 0)``                       ``+ minDominatingSet(``                             ``root->right, 1, 0),``                   ``minDominatingSet(``                       ``root->left, 0, 0)``                       ``+ minDominatingSet(``                             ``root->right, 0, 0));``    ``}` `    ``// If the current node is neither covered nor``    ``// needs to be selected compulsorily``    ``int` `ans = 1``              ``+ minDominatingSet(``                    ``root->left, 1, 0)``              ``+ minDominatingSet(``                    ``root->right, 1, 0);` `    ``if` `(root->left) {``        ``ans = min(ans,``                  ``minDominatingSet(``                      ``root->left, 0, 1)``                      ``+ minDominatingSet(``                            ``root->right, 0, 0));``    ``}``    ``if` `(root->right) {``        ``ans = min(ans,``                  ``minDominatingSet(``                      ``root->left, 0, 0)``                      ``+ minDominatingSet(``                            ``root->right, 0, 1));``    ``}` `    ``// Store the result``    ``return` `dp[root->data]``             ``[covered]``             ``[compulsory]``           ``= ans;``}` `// Driver code``signed` `main()``{``    ``// initialising the DP array``    ``memset``(dp, -1, ``sizeof``(dp));` `    ``// Constructing the tree``    ``Node* root = newNode(1);``    ``root->left = newNode(2);``    ``root->left->left = newNode(3);``    ``root->left->right = newNode(4);``    ``root->left->left->left = newNode(5);``    ``root->left->left->left->left = newNode(6);``    ``root->left->left->left->right = newNode(7);``    ``root->left->left->left->right->right = newNode(10);``    ``root->left->left->left->left->left = newNode(8);``    ``root->left->left->left->left->right = newNode(9);` `    ``cout << minDominatingSet(root, 0, 0) << endl;` `    ``return` `0;``}`

## Java

 `// Java program to find the size of the``//minimum dominating set of the tree``import` `java.util.*;` `class` `GFG{` `static` `final` `int` `N = ``1005``;` `// Definition of a tree node``static` `class` `Node``{``    ``int` `data;``    ``Node left, right;``};` `// Helper function that allocates a``// new node``static` `Node newNode(``int` `data)``{``    ``Node node = ``new` `Node();``    ``node.data = data;``    ``node.left = node.right = ``null``;``    ``return` `node;``}` `// DP array to precompute``// and store the results``static` `int` `[][][]dp = ``new` `int``[N][``5``][``5``];` `// minDominatingSettion to return the size of``// the minimum dominating set of the array``static` `int` `minDominatingSet(Node root,``                            ``int` `covered,``                            ``int` `compulsory)``{``    ``// Base case``    ``if` `(root == ``null``)``        ``return` `0``;``    ` `    ``// Setting the compulsory value if needed``    ``if` `(root.left != ``null` `&&``       ``root.right != ``null` `&&``       ``covered > ``0``)``        ``compulsory = ``1``;` `    ``// Check if the answer is already computed``    ``if` `(dp[root.data][covered][compulsory] != -``1``)``        ``return` `dp[root.data][covered][compulsory];` `    ``// If it is compulsory to select``    ``// the node``    ``if` `(compulsory > ``0``)``    ``{``        ` `        ``// Choose the node and set its``        ``// children as covered``        ``return` `dp[root.data][covered][compulsory] = ``1` `+``                 ``minDominatingSet(root.left, ``1``, ``0``) +``                 ``minDominatingSet(root.right, ``1``, ``0``);``    ``}` `    ``// If it is covered``    ``if` `(covered > ``0``)``    ``{``        ``return` `dp[root.data][covered]``                 ``[compulsory] = Math.min(``1` `+``                  ``minDominatingSet(root.left, ``1``, ``0``) +``                  ``minDominatingSet(root.right, ``1``, ``0``),``                  ``minDominatingSet(root.left, ``0``, ``0``)+``                  ``minDominatingSet(root.right, ``0``, ``0``));``    ``}` `    ``// If the current node is neither covered nor``    ``// needs to be selected compulsorily``    ``int` `ans = ``1` `+ minDominatingSet(root.left, ``1``, ``0``) +``                  ``minDominatingSet(root.right, ``1``, ``0``);` `    ``if` `(root.left != ``null``)``    ``{``        ``ans = Math.min(ans,``              ``minDominatingSet(root.left, ``0``, ``1``) +``              ``minDominatingSet(root.right, ``0``, ``0``));``    ``}``    ``if` `(root.right != ``null``)``    ``{``        ``ans = Math.min(ans,``              ``minDominatingSet(root.left, ``0``, ``0``) +``              ``minDominatingSet(root.right, ``0``, ``1``));``    ``}` `    ``// Store the result``    ``return` `dp[root.data][covered][compulsory] = ans;``}` `// Driver code``public` `static` `void` `main(String[] args)``{``    ` `    ``// Initialising the DP array``    ``for``(``int` `i = ``0``; i < N; i++)``    ``{``        ``for``(``int` `j = ``0``; j < ``5``; j++)``        ``{``            ``for``(``int` `l = ``0``; l < ``5``; l++)``                ``dp[i][j][l] = -``1``;``        ``}``    ``}` `    ``// Constructing the tree``    ``Node root = newNode(``1``);``    ``root.left = newNode(``2``);``    ``root.left.left = newNode(``3``);``    ``root.left.right = newNode(``4``);``    ``root.left.left.left = newNode(``5``);``    ``root.left.left.left.left = newNode(``6``);``    ``root.left.left.left.right = newNode(``7``);``    ``root.left.left.left.right.right = newNode(``10``);``    ``root.left.left.left.left.left = newNode(``8``);``    ``root.left.left.left.left.right = newNode(``9``);` `    ``System.out.print(minDominatingSet(``        ``root, ``0``, ``0``) + ``"\n"``);``}``}` `// This code is contributed by amal kumar choubey`

## Python3

 `# Python3 program to find the size of the``# minimum dominating set of the tree */``N ``=` `1005`` ` `# Definition of a tree node``class` `Node:``    ` `    ``def` `__init__(``self``, data):``        ` `        ``self``.data ``=` `data``        ``self``.left ``=` `None``        ``self``.right ``=` `None``     ` `# Helper function that allocates a``# new node``def` `newNode(data):` `    ``node ``=` `Node(data)``    ``return` `node`` ` `# DP array to precompute``# and store the results``dp ``=` `[[[``-``1` `for` `i ``in` `range``(``5``)] ``for` `j ``in` `range``(``5``)] ``for` `k ``in` `range``(N)];`` ` `# minDominatingSettion to return the size of``# the minimum dominating set of the array``def` `minDominatingSet(root, covered, compulsory):` `    ``# Base case``    ``if` `(``not` `root):``        ``return` `0``;`` ` `    ``# Setting the compulsory value if needed``    ``if` `(``not` `root.left ``and` `not` `root.right ``and` `not` `covered):``        ``compulsory ``=` `True``;`` ` `    ``# Check if the answer is already computed``    ``if` `(dp[root.data][covered][compulsory] !``=` `-``1``):``        ``return` `dp[root.data][covered][compulsory];`` ` `    ``# If it is compulsory to select``    ``# the node``    ``if` `(compulsory):``        ` `        ``dp[root.data][covered][compulsory] ``=` `1` `+` `minDominatingSet(root.left, ``1``, ``0``) ``+` `minDominatingSet(root.right, ``1``, ``0``);``        ` `        ``# Choose the node and set its children as covered``        ``return` `dp[root.data][covered][compulsory]``     ` `    ``# If it is covered``    ``if` `(covered):``        ``dp[root.data][covered][compulsory] ``=` `min``(``1` `+` `minDominatingSet(root.left, ``1``, ``0``) ``+` `minDominatingSet(root.right, ``1``, ``0``),minDominatingSet(root.left, ``0``, ``0``)``+` `minDominatingSet(root.right, ``0``, ``0``));``        ``return` `dp[root.data][covered][compulsory]``     ` `    ``# If the current node is neither covered nor``    ``# needs to be selected compulsorily``    ``ans ``=` `1` `+` `minDominatingSet(root.left, ``1``, ``0``) ``+` `minDominatingSet(root.right, ``1``, ``0``);`` ` `    ``if` `(root.left):``        ``ans ``=` `min``(ans, minDominatingSet(root.left, ``0``, ``1``) ``+` `minDominatingSet(root.right, ``0``, ``0``));``    ` `    ``if` `(root.right):``        ``ans ``=` `min``(ans, minDominatingSet( root.left, ``0``, ``0``) ``+` `minDominatingSet(root.right, ``0``, ``1``));``     ` `    ``# Store the result``    ``dp[root.data][covered][compulsory]``=` `ans;``    ``return` `ans` `# Driver code``if` `__name__``=``=``'__main__'``:``     ` `    ``# Constructing the tree``    ``root ``=` `newNode(``1``);``    ``root.left ``=` `newNode(``2``);``    ``root.left.left ``=` `newNode(``3``);``    ``root.left.right ``=` `newNode(``4``);``    ``root.left.left.left ``=` `newNode(``5``);``    ``root.left.left.left.left ``=` `newNode(``6``);``    ``root.left.left.left.right ``=` `newNode(``7``);``    ``root.left.left.left.right.right ``=` `newNode(``10``);``    ``root.left.left.left.left.left ``=` `newNode(``8``);``    ``root.left.left.left.left.right ``=` `newNode(``9``);`` ` `    ``print``(minDominatingSet(root, ``0``, ``0``))``  ` `  ``# This code is contributed by rutvik_56`

## C#

 `// C# program to find the size of the``//minimum dominating set of the tree``using` `System;``class` `GFG{` `static` `readonly` `int` `N = 1005;` `// Definition of a tree node``public` `class` `Node``{``    ``public`` ``int` `data;``    ``public`` ``Node left, right;``};` `// Helper function that allocates a``// new node``public` `static` `Node newNode(``int` `data)``{``    ``Node node = ``new` `Node();``    ``node.data = data;``    ``node.left = node.right = ``null``;``    ``return` `node;``}` `// DP array to precompute``// and store the results``static` `int` `[,,]dp = ``new` `int``[N, 5, 5];` `// minDominatingSettion to return the size of``// the minimum dominating set of the array``static` `int` `minDominatingSet(Node root,``                            ``int` `covered,``                            ``int` `compulsory)``{``    ``// Base case``    ``if` `(root == ``null``)``        ``return` `0;``    ` `    ``// Setting the compulsory value if needed``    ``if` `(root.left != ``null` `&&``       ``root.right != ``null` `&&``       ``covered > 0)``        ``compulsory = 1;` `    ``// Check if the answer is already computed``    ``if` `(dp[root.data, covered, compulsory] != -1)``        ``return` `dp[root.data, covered, compulsory];` `    ``// If it is compulsory to select``    ``// the node``    ``if` `(compulsory > 0)``    ``{``        ` `        ``// Choose the node and set its``        ``// children as covered``        ``return` `dp[root.data, covered, compulsory] = 1 +``                    ``minDominatingSet(root.left, 1, 0) +``                   ``minDominatingSet(root.right, 1, 0);``    ``}` `    ``// If it is covered``    ``if` `(covered > 0)``    ``{``        ``return` `dp[root.data, covered, compulsory] = Math.Min(1 +``                             ``minDominatingSet(root.left, 1, 0) +``                             ``minDominatingSet(root.right, 1, 0),``                             ``minDominatingSet(root.left, 0, 0)+``                            ``minDominatingSet(root.right, 0, 0));``    ``}` `    ``// If the current node is neither covered nor``    ``// needs to be selected compulsorily``    ``int` `ans = 1 + minDominatingSet(root.left, 1, 0) +``                  ``minDominatingSet(root.right, 1, 0);` `    ``if` `(root.left != ``null``)``    ``{``        ``ans = Math.Min(ans,``              ``minDominatingSet(root.left, 0, 1) +``              ``minDominatingSet(root.right, 0, 0));``    ``}``    ``if` `(root.right != ``null``)``    ``{``        ``ans = Math.Min(ans,``              ``minDominatingSet(root.left, 0, 0) +``              ``minDominatingSet(root.right, 0, 1));``    ``}` `    ``// Store the result``    ``return` `dp[root.data, covered, compulsory] = ans;``}` `// Driver code``public` `static` `void` `Main(String[] args)``{``    ` `    ``// Initialising the DP array``    ``for``(``int` `i = 0; i < N; i++)``    ``{``        ``for``(``int` `j = 0; j < 5; j++)``        ``{``            ``for``(``int` `l = 0; l < 5; l++)``                ``dp[i, j, l] = -1;``        ``}``    ``}` `    ``// Constructing the tree``    ``Node root = newNode(1);``    ``root.left = newNode(2);``    ``root.left.left = newNode(3);``    ``root.left.right = newNode(4);``    ``root.left.left.left = newNode(5);``    ``root.left.left.left.left = newNode(6);``    ``root.left.left.left.right = newNode(7);``    ``root.left.left.left.right.right = newNode(10);``    ``root.left.left.left.left.left = newNode(8);``    ``root.left.left.left.left.right = newNode(9);` `    ``Console.Write(minDominatingSet``                  ``root, 0, 0) + ``"\n"``);``}``}` `// This code is contributed by Rohit_ranjan`
Output:
`3`

Time Complexity:O(N*log N)

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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

My Personal Notes arrow_drop_up