Vertex Cover on a Tree
Last updated
Last updated
Given an undirected unweighted graph , a vertex cover is defined as a set of nodes where every edge is adjacent to at least one node in .
A minimum vertex cover is a vertex cover with the minimum possible number of nodes.
In general, Minimum vertex cover is an NP-complete problem, i.e., there is no polynomial time algorithm unless .
However, there is an easy 2-approximation algorithm via matching (A 2-approximation means that your solution will be at most 2 times worse than the optimal solution).
We are solving an easier problem in this case: given an undirected unweighted tree, and a root of the tree , we need to find the minimum vertex cover of the tree.
As always, let us follow our DP recipe:
Define subproblems (and base cases)
Identify optimal substructure
Solve problem using sub-problems
Write (pseudo)code
An initial attempt might try to store the size of the vertex cover of the subtree rooted at the node and use it to solve larger subproblems. But that alone is not sufficient because we wouldnāt know whether we are forced to include its parent or not unless we know whether the child is in the vertex cover or not - so this leads to 2 cases: node in vertex cover and node not in vertex cover. This is sufficient information to compute the vertex cover of the parent too.
Note that it is not sufficient alone to store merely the size of the vertex cover of the subtree rooted at that node for each node. We need to know whether that node itself is included or not. In particular, if the child is not included in the vertex cover of its subtree, the parent must be included (only then the edge connecting them can be adjacent to a node in the vertex cover). Moreover, even if a child is included in its vertex cover for the subtree, it may be reasonable to include the parent in case the parent has other children who are not included in their respective sub-vertex covers.
Define size of a vertex cover in subtree rooted at node , if is NOT covered. Similarly, define size of a vertex cover in subtree rooted at node , if IS covered. For example,
After a bit of observation, you should realise that the recurrence relation is as follows:
Look how elegantly we realised that using subtrees as subproblems is the right way to go - the importance of identifying this overlapping subproblem cannot be overstated.
Alternatively, you can think like this.
Each edge is explored once since each subproblem involves exploring children edges.
So, for each node you need to consider whether it is in the cover or not. Hence, there are subproblems that we need to solve. (Note that the number of subproblems is NOT - We are not considering it like āfor each node, we can either include or not include. So, check all possible ways and pick the minimum that satisfies vertex cover propertyā. We are just looking at two possibilities for each node (INDEPENDENT of other nodes in the tree! we are not chaining the results so thereās no need to multiply the subproblems of all nodes together)
The base case is in case of leaves: and .
where . In other words, if you donāt cover the node, you better make sure to cover all the children so that each edge between and its children is covered.
. That is, if you are covering the parent, then it is not mandatory to cover its children but often it is optimal to cover some of the children too (depending on the lower subtrees). So, you take the minimum of the two to decide whether to cover each child or not.
Then our final answer is - whether to cover the root or not.
Youāre looking at each edge exactly once and each node exactly twice (once when determining its own values, and once when trying to determine itās parents value - except the root). So, the running time is . But observe that our input is a tree and hence, . Thus, running time is .
There are subproblems:
Hence,