![]() |
VOOZH | about |
Dynamic Programming (DP) on trees is a powerful algorithmic technique commonly used in competitive programming. It involves solving various tree-related problems by efficiently calculating and storing intermediate results to optimize time complexity. By using the tree structure, DP on trees allows programmers to find solutions for a wide range of problems, making it an essential skill in competitive programming.
Dynamic Programming (DP) on trees is a technique used to efficiently solve problems involving tree structures by breaking them down into smaller subproblems and storing intermediate results to avoid redundant calculations.
Lets, understand the Dynamic Programming (DP) on by a problem:
Given a tree consisting of N Nodes and N-1 edges. The task is to select the maximum set of edges such that each vertex is part of at most one of the selected edges (no two edges share a common end point) i.e., if we select an edge connecting vertex u and v, then we cannot select any other edge connected by vertex u or vertex v.
The problem can be solved using DP on Tree in the following way:
Root the tree at any of node(say 1).
For each node we have 2 options, select a edge from the current from the current vertex to any of his child or do not select any edge passing through the current vertex.
dp[v][0]= Maximum set of edges selected in the subtree rooted at vertex v such that no two edges have a common end point, if we do not select any edge passing through vertex v.
dp[v][1]= Maximum set of edges selected in the subtree rooted at vertex v such that no two edges have a common end point, if we select a edge passing through vertex v.
Calculating dp[v][0]: Since dp[v][0] defines the state where we do not take any edge passing through vertex v (i.,e, v->u , where u is child of vertex). So for the all child nodes of vertex v we can either take an edge passing through it or do not take, and all the children of vertex v will be independent of each other in this case.
, where u is child of vertex v.
Calculating dp[v][1]: dp[v][1] defines the state where we do take a edge passing through vertex v (i.,e, v->u , where u is child of vertex).
Suppose we select a edge (v->u), then we cannot choose any other edge passing through vertex u. So will need dp[u][0] in this case, and for all other children of vertex v, we can either choose an edge passing through it or do not choose it as done in above case and we can use that state (dp[v][0]) for calculating this state.
, for all child u of vertex v.
Since we have chosen vertex as the 1 root. Our answer will be max(dp[1][0], dp[1][1]).
Below is the implementation of above approach:
2
Time Complexity: O(N)
Auxilary Space: O(N)
The Rerooting technique is a method used in tree algorithms to efficiently compute values associated with nodes or subtrees of a rooted tree when the tree's root can be moved or "rerooted" to different nodes in the tree. This technique is particularly useful when you want to calculate values for various nodes or subtrees in a tree, but you don't want to traverse the entire tree for each query.
The rerooting technique is commonly used in problems that require dynamic programming on trees, such as finding optimal paths, maximum values, or minimum values in subtrees. It allows you to reposition the root and update the values in a way that minimizes redundant work, resulting in more efficient algorithms for various tree-related problems.
Lets, understand the Rerooting Techique by a problem:
Given a tree consisting of N Nodes and N-1 edges. The task is to determine for each node the sum of distance to all other nodes.
The problem can be solved using Rerooting technique in the following way:
Root the tree at node 1.
We will need 2 dp arrays for this problem.
dp1[v]: The sum of distance of node v from all the other nodes in subtree rooted at vertex v.
dp2[v]: The sum of distance of node v from all the other other nodes in the tree.
For the root, dp1[1] will be equal to dp2[1] since, all the nodes of the tree lie in the subtree rooted at vertex 1.
dp1[v] can be calculated by:-
, where u is the child of vertex v and sub[u] is the number of nodes in subtree rooted at vertex u.
Since dp2[1]=dp1[1], answer for the root have been determined.
Now suppose we know the final answer for vertex v, dp2[v] (sum of distance of node v from all other nodes). Now we want to compute the answer for node u, which is a child of vertex v.
dp2[u], (sum of distance from node u to all other nodes in tree) will be the sum of following two parts:
We already computed dp1[u], which is sum of distance from node u to all other nodes in the subtree rooted at node u.
This will be calculated with the help of dp2[v](sum of distance from node v to all other nodes in tree)Sum of distance from node v to all other nodes excluding the subtree rooted at vertex v will be
From this we can calculate sum of distance from node u to all other nodes excluding the subtree rooted at vertex u by adding (N-sub[u]) to above equation, since N- sub[u] gives the total number of nodes excluding the nodes in the subtree rooted at vertex u.
Summing the above two parts we get:
This can be further simplified to:
Below is the implementation of above approach:
6 9 5 8 8
Time Complexity: O(N)
Auxiliary Space: O(N)
Dynamic Programming (DP) on trees is a powerful technique for solving a variety of problems involving tree structures. Here is a comprehensive overview of its applications and considerations:
Maximum sum of the node values from root to any of the leaves without re-visiting any node |
Maximum height of Tree when any Node can be considered as Root |
Related Article: