hdu 1054 Strategic Game

来源:互联网 发布:返利网淘宝返利比例 编辑:程序博客网 时间:2024/06/04 18:53

我的第一题树形DP,比较简单

简单的讲下我的思路。仅表纪念

对于一个节点来说有可能的情况只有两个:一个是这个节点站守卫,那么它的孩子有两种情况,一种是孩子节点上也站守卫,另一种是孩子节点上不站守卫,然后取这两种情况当中的较小值;第二个这个节点上不站守卫,那么为了保证每条边都能被守卫到,那么它的孩子肯定是要站守卫的。

其中dp1表示出现第一个情况时该节点最少的守卫数量,dp2表示第二个情况时该节点最少的守卫数量,然后再取这两者中的较小值。

在main函数中注意一些小的处理


#include<iostream>#include<string.h>using namespace std;const int maxn = 1500;struct node{int num;int next[maxn];}p[maxn];int dp1[maxn],dp2[maxn];int min(int a,int b){return a < b? a:b;}int dp(int root){dp1[root] = 1;dp2[root] = 0;for(int i = 0;i < p[root].num;i++){int tmp = p[root].next[i];dp(tmp);dp2[root] += dp1[tmp];dp1[root] += min(dp1[tmp],dp2[tmp]);}return min(dp1[root],dp2[root]);}int main(){int n;while(scanf("%d",&n)!=EOF){memset(dp1,0,sizeof(dp1));memset(dp2,0,sizeof(dp2));int a,b,root;for(int i = 0;i < n ;i++){scanf("%d:(%d)",&a,&b);p[a].num = b;if(i==0)root = a;for(int j = 0;j<p[a].num;j++)scanf("%d",&p[a].next[j]);}printf("%d\n",dp(root));}return 0;}


0 0