hdu_1054_Strategic Game
来源:互联网 发布:linux -l 怎么用 编辑:程序博客网 时间:2024/05/19 04:02
树形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 10000struct 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;}