What is a good algorithm for getting the minimum vertex cover of a tree?

后端 未结 7 560
感动是毒
感动是毒 2020-12-28 16:55

What is a good algorithm for getting the minimum vertex cover of a tree?

INPUT:

The node\'s neighbours.

OUTPUT:

The minimum number of vertice

相关标签:
7条回答
  • 2020-12-28 17:03

    I would simply use a linear program to solve the minimum vertex cover problem. A formulation as an integer linear program could look like the one given here: ILP formulation

    I don't think that your own implementation would be faster than these highly optimized LP solvers.

    0 讨论(0)
  • 2020-12-28 17:06

    I didn't fully understand after reading the answers here, so I thought I'd post one from here

    The general idea is that you root the tree at an arbitrary node, and ask whether that root is in the cover or not. If it is, then you calculate the min vertex cover of the subtrees rooted at its children by recursing. If it isn't, then every child of the root must be in the vertex cover so that every edge between the root and its children is covered. In this case, you recurse on the root's grandchildren.

    So for example, if you had the following tree:

        A
       / \
      B   C
     / \ / \
    D  E F  G
    

    Note that by inspection, you know the min vertex cover is {B, C}. We will find this min cover.

    Here we start with A.

    A is in the cover

    We move down to the two subtrees of B and C, and recurse on this algorithm. We can't simply state that B and C are not in the cover, because even if AB and AC are covered, we can't say anything about whether we will need B and C to be in the cover or not.

    (Think about the following tree, where both the root and one of its children are in the min cover ({A, D})

      A
     /|\___
    B C    D
          /|\
         E F G
    

    )

    A is not in the cover

    But we know that AB and AC must be covered, so we have to add B and C to the cover. Since B and C are in the cover, we can recurse on their children instead of recursing on B and C (even if we did, it wouldn't give us any more information).

    "Formally"

    Let C(x) be the size of the min cover rooted at x.

    Then,

    C(x) = min ( 
                1 + sum ( C(i) for i in x's children ),                    // root in cover
                len(x's children) + sum( C(i) for i in x's grandchildren)  // root not in cover
                )
    
    0 讨论(0)
  • 2020-12-28 17:13

    I hope here you can find more related answer to your question.


    I was thinking about my solution, probably you will need to polish it but as long as dynamic programing is in one of your tags you probably need to:

    1. For each u vertex define S+(u) is cover size with vertex u and S-(u) cover without vertex u.
    2. S+(u)= 1 + Sum(S-(v)) for each child v of u.
    3. S-(u)=Sum(max{S-(v),S+(v)}) for each child v of u.
    4. Answer is max(S+(r), S-(r)) where r is root of your tree.

    After reading this. Changed the above algorithm to find maximum independent set, since in wiki article stated

    A set is independent if and only if its complement is a vertex cover.

    So by changing min to max we can find the maximum independent set and by compliment the minimum vertex cover, since both problem are equivalent.

    0 讨论(0)
  • 2020-12-28 17:13

    We need to find the minimum vertex cover for each node we have to choices to make, either to include it or not to include it. But according to the problem for each edge (u, v), either of 'u' or 'v' should be in the cover so we need to take care that if the current vertex is not included then we should include its children, and if we are including the current vertex then, we may or may not include its children based on optimal solution.

    Here, DP1[v] for any vertex v = When we include it. DP2[v] for any vertex v = when we don't include it.

    DP1[v] = 1 + sum(min(DP2[c], DP1[c])) - this means include current and may or may not include its children, based on what is optimal.

    DP2[v] = sum(DP1[c]) - this means not including current then we need to include children of current vertex. Here, c is the child of vertex v.

    Then, our solution is min(DP1[root], DP2[root])

    #include <bits/stdc++.h>
    using namespace std;
    
    vector<vector<int> > g;
    
    int dp1[100010], dp2[100010];
    
    void dfs(int curr, int p){
        for(auto it : g[curr]){
            if(it == p){
                continue;
            }
            dfs(it, curr);
            dp1[curr] += min(dp1[it], dp2[it]);
            dp2[curr] += dp1[it];
        }
        dp1[curr] += 1;
    }
    
    int main(){
        int n;
        cin >> n;
        g.resize(n+1);
        for(int i=0 ; i<n-1 ; i++){
            int u, v;
            cin >> u >> v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        dfs(1, 0);
        cout << min(dp1[1], dp2[1]);
        return 0;
    } 
    
    0 讨论(0)
  • 2020-12-28 17:16

    We can use a DFS based algorithm to solve this probelm:

    DFS(node x)
    {
    
        discovered[x] = true;
    
        /* Scan the Adjacency list for the node x*/
        while((y = getNextAdj() != NULL)
        {
    
            if(discovered[y] == false)
            {
    
                DFS(y);
    
               /* y is the child of node x*/
               /* If child is not selected as a vertex for minimum selected cover
                then select the parent */ 
               if(y->isSelected == false)
               {
                   x->isSelected = true;
               }
            }
       }
    }
    

    The leaf node will never be selected for the vertex cover.

    0 讨论(0)
  • 2020-12-28 17:18

    T(V,E) is a tree, which implies that for any leaf, any minimal vertex cover has to include either the leaf or the vertex adjacent to the leaf. This gives us the following algorithm to finding S, the vertex cover:

    1. Find all leaves of the tree (BFS or DFS), O(|V|) in a tree.
    2. If (u,v) is an edge such that v is a leaf, add u to the vertex cover, and prune (u,v). This will leave you with a forest T_1(V_1,E_1),...,T_n(U_n,V_n).
    3. Now, if V_i={v}, meaning |V_i|=1, then that tree can be dropped since all edges incident on v are covered. This means that we have a termination condition for a recursion, where we have either one or no vertices, and we can compute S_i as the cover for each T_i, and define S as all the vertices from step 2 union the cover of each T_i.

    Now, all that remains is to verify that if the original tree has only one vertex, we return 1 and never start the recursion, and the minimal vertex cover can be computed.

    Edit:

    Actually, after thinking about it for a bit, it can be accomplished with a simple DFS variant.

    0 讨论(0)
提交回复
热议问题