hdu1520 Anniversary party 简单树形DP

本文详细解析了HDU 1520问题的树形动态规划解决方案,通过定义状态dp[root][1]表示以root为根节点的子树,且root本身参加party的最优值;dp[root][0]表示root不参加的情况。文章提供了完整的代码实现。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520

思路:树形DP的入门题

定义dp[root][1]表示以root为根节点的子树,且root本身参加party的最优值,那么dp[root][1]+=Σdp[son][0]+happy[root];

dp[root][0]表示以root为跟节点且root本身没有参加的最优值,那么dp[root][0]+=max(dp[son][0],dp[son][1]);

如果不理解,可以参考我对hdu1054的解释。

代码如下:

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 using namespace std;
 6 #define MAX 6010
 7 int dp[MAX][2];
 8 int happy[MAX];
 9 class node
10 {
11   public:
12   int to;
13   int next;
14 };
15 node edge[2*MAX];
16 int head[MAX];
17 int vis[MAX];
18 int n;
19 int tol;
20 void init()
21 {
22   memset(vis,0,sizeof(vis));
23   memset(head,-1,sizeof(head));
24   memset(dp,0,sizeof(dp));
25   tol=0;
26 }
27 void Build_Tree(int u,int v)
28 {
29         edge[tol].to=v;
30         edge[tol].next=head[u];
31         head[u]=tol++;
32 }
33 void dfs(int root)
34 {
35    vis[root]=1;
36    int hy=happy[root];
37    for(int i=head[root];i!=-1;i=edge[i].next)
38    {
39      if(vis[edge[i].to]) continue;
40      int son=edge[i].to;
41      dfs(son);
42 
43      dp[root][1]+=dp[son][0];
44      dp[root][0]+=max(dp[son][1],dp[son][0]);
45    }
46    dp[root][1]+=hy;
47 }
48 int main()
49 {
50    while(scanf("%d",&n)!=EOF)
51    {
52      init();
53      for(int i=1;i<=n;i++)
54        scanf("%d",&happy[i]);
55        int u,v;
56 
57        while(scanf("%d%d",&v,&u)!=EOF&&v&&u)
58        {
59         Build_Tree(u,v);
60         Build_Tree(v,u);
61        }
62     dfs(1);
63     cout<<max(dp[1][1],dp[1][0])<<endl;
64    }
65   return 0;
66  }
View Code

 

 

转载于:https://www.cnblogs.com/xiaozhuyang/p/hdu1520.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值