1

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!

Lionblaze16
  • 23
  • 1
  • 7

1 Answers1

1

The first algorithm actually works. In a minimum vertex cover each edge has to be incident to at least one vertex. In your "counterexample" neither vertex 3 nor 4 are marked, therefore the edge (3,4) doesn't have an incident vertex in the set. So {2, 5} is not a vertex cover.

Your approach doesn't work at all. First of all, I think you still work with a wrong definition of a minimum vertex cover. I'm guessing, that you think, that each vertex has to be touched by an edge incident to a marked vertex.

And even if you use a wrong definition, your approach will not work. A vertex that has distance 3 to a marked parent vertex doesn't have to be marked. Look at this example:

  0
  |
  1
  |
  2
 / \
3   4
    |
    5

In this example if vertex 0 is marked, then the vertices 3 and 4 get also marked, because they are distance 3 from the top. But it is not necessary to mark vertex 4, instead we could also mark vertex 5. Obviously this would give the same number of vertices in this example, but I'm sure you could extend this to a bigger example, where your approach fails.

Solution idea for the different definition:

I believe that a greedy solution works. (There is also a greedy algorithm for the minimum vertex cover). Start by the leaves go upwards to the center. Only mark nodes that are necessary to mark.

You can do this again with depth first search and DP. Let dp[v] be the shortest distance between v and a marked node in the subtree of v. To compute v, first compute all dp values of the children nodes and then decide, if it is necessary to mark it or not. If any child has dp[child] = 2, then you need to mark v and put dp[v] = 0. Otherwise you don't have to mark it and dp[v] = min(dp[children] + 1). At the end you might also need to mark the root node.

Note: I have not tested this.

Jakube
  • 2,618
  • 2
  • 18
  • 39
  • The issue was that I misunderstood the definition of a minimum vertex cover. Thank you for clearing that up, but could you give me a hint on how to find the minimum sized set of marked vertices such that each vertex has to be touched by an edge incident to a marked vertex? – Lionblaze16 Jul 09 '17 at 16:39
  • @Lionblaze16 I've added an idea to my post. Might work, but I'm not 100% sure. – Jakube Jul 09 '17 at 17:19