树形dp,状态:dp[u][1], dp[u][0]分别表示第u个节点放与不放兵
状态转移方程表示为:
dp[u][0] = sum{dp[v[1]};
dp[u][1] = sum{dp[v][0], dp[v][1]}
ans = min(dp[root][0], dp[root][1]);
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define SELECT 1
#define UNSELECT 0
#define MAXN 1510
#define MAXM 10000
struct EDGE {
int v, next;
}edge[MAXM];
int head[MAXN], dp[MAXN][2], is_root[MAXN], e_cnt;
void insert_arc(const int &u, const int &v)
{
edge[e_cnt].v = v; edge[e_cnt].next = head[u]; head[u] = e_cnt ++;
}
int build_tree(const int &node_cnt)
{
char tmp[MAXN/100];
int src, des, child_cnt;
memset(is_root, -1, sizeof(is_root));
e_cnt = 0; memset(head, -1, sizeof(head));
for(int i = 0; i < node_cnt; i ++) {
scanf("%s", tmp); sscanf(tmp, "%d:(%d)", &src, &child_cnt);
for(int j = 0; j < child_cnt; j ++) {
scanf("%d", &des);
is_root[des] = 0; insert_arc(src, des);
}
}
for(int i = 0; i < node_cnt; i ++) {
if( is_root[i] ) {
return i;
}
}
}
int dfs(const int &u, const int &mark)
{
if( -1 != dp[u][mark] ) {
return dp[u][mark];
}
if( -1 == head[u] ) {
return mark;
}
dp[u][mark] = mark;
for(int i = head[u]; -1 != i; i = edge[i].next) {
dp[edge[i].v][mark] = (-1 == dp[edge[i].v][mark])? dfs(edge[i].v, mark) : dp[edge[i].v][mark];
dp[edge[i].v][!mark] = (-1 == dp[edge[i].v][!mark])? dfs(edge[i].v, !mark) : dp[edge[i].v][!mark];
dp[u][mark] += (mark)?min(dp[edge[i].v][!mark], dp[edge[i].v][mark]) : dp[edge[i].v][!mark];
}
return dp[u][mark];
}
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int node_cnt, root;
while( ~scanf("%d", &node_cnt) ) {
root = build_tree(node_cnt);
memset(dp, -1, sizeof(dp));
printf("%d\n", min(dfs(root, SELECT), dfs(root, UNSELECT)));
}
return 0;
}
hdu_1054_Strategic Game
最新推荐文章于 2021-08-11 06:38:52 发布