给定一个没有自循环和平行边的无向图。
我的目标是找到minimum edge cover
。我开始知道可以使用bitmask DP
有效地完成它。我已经尝试了很多,但无法弄清楚如何定义state of DP
。请帮助决定DP
州。
答案 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");
*/