There have been many posts in the past regarding this topic from a quick search on the site, many of which use this dynamic programming recurrence:
C(x) = min(1 + sum (C(i) for i in x's children), len(x's children) + sum(C(i) for i in x's grandchildren))
Assuming the tree is rooted at node 1, I tried this algorithm against the chain of nodes 1-2-3-4-5-6, to get the following C(i):
| C(1) | C(2) | C(3) | C(4) | C(5) | C(6) |
| 3 | 2 | 2 | 1 | 1 | 1 |
However, the correct answer for C(1) should be 2, which is achieved by marking nodes 2 and 5.
I decided to try my own approach which is detailed below:
int solve(int curr, int height){
if(dp[curr][height] > -1) return dp[curr][height];
if(int(children[curr].size()) == 0) return dp[curr][height] = height > 1 ? 1 : 0;
if(height == 3){
int ret = 1;
for(int i = 0; i < int(children[curr].size()); i++){
int next = children[curr][i];
ret += solve(next, 1);
}
return dp[curr][height] = ret;
}
int ret1 = 0; int ret2 = 1;
if(height == 2){
for(int i = 0; i < int(children[curr].size()); i++){
int next = children[curr][i];
ret1 += solve(next, 3); ret2 += solve(next, 1);
}
return dp[curr][height] = min(ret1, ret2);
}
for(int i = 0; i < int(children[curr].size()); i++){
int next = children[curr][i];
ret1 += solve(next, 2); ret2 += solve(next, 1);
}
return dp[curr][height] = min(ret1, ret2);
}
curr is the current node that we are at, and height is the distance away from the closest marked node above it. The idea is that once a node has height = 3, it must be marked in that particular path. Otherwise, we can skip marking it for now. The exception is a leaf node, which must be marked if an adjacent node is not marked.
Can someone please verify the validity of my approach, and also explain why the first algorithm fails the chain test?
Thanks in advance!