使用动态编程查找最小边缘覆盖的有效方法

时间:2017-04-04 05:32:06

标签: algorithm graph dynamic-programming graph-algorithm

给定一个没有自循环和平行边的无向图。

我的目标是找到minimum edge cover。我开始知道可以使用bitmask DP有效地完成它。我已经尝试了很多,但无法弄清楚如何定义state of DP。请帮助决定DP州。

1 个答案:

答案 0 :(得分:0)

我没有使用位掩码实现,我的动态编程方法有2个状态 -

dp[u][hashGuard] // curerntly in u node, this depicts minimum guards required for rest of the nodes encountered later

过渡功能 -

// In node u, we have no guards, so we must have to put guards on adjacent nodes
dp[u][0] += dp[v][1] for all adjacent nodes v from u

// In current node u, we have guard. So we can try to minimize the number of guards by puting guards on adjacent nodes or by not putting
dp[u][1] += min(dp[v][1], dp[v][0])  for all adjacent nodes v from u

这是我的C ++实现 -

// Assuming the graph is a tree. you can transform it for graph by using a visited flag instead of parent array
#define MAX 100001

int dp[MAX << 2][2];
int parent[MAX];
vector <int> adj[MAX];

int minVertexCover(int node, bool hasGuard) {

    if( (int)adj[node].size() == 0 ) return 0;
    if( dp[node][hasGuard] != -1 ) return dp[node][hasGuard];

    int sum = 0;
    for(int i = 0; i < (int)adj[node].size(); i++) {
        int v = adj[node][i];
        if( v != parent[node] ) {
            parent[v] = node;
            if(!hasGuard) {
                sum += minVertexCover(v, true);
            } else {
                sum += min( minVertexCover(v, false), minVertexCover(v, true) );
            }
        }
    }
    return dp[node][hasGuard] = sum + hasGuard;
}

/*
usage:
// graph input
// if node 1 and node 2 connected, then 
// adj[2].push_back(1);
// adj[1].push_back(2)

result = min( minVertexCover(1, false), minVertexCover(1, true) );
if(n > 1) 
    printf("%d\n", result);
else 
    printf("1\n");
*/