首页 > 其他 > 详细

HDU 1520 Anniversary party (树形DP,入门)

时间:2015-09-14 11:57:41      阅读:260      评论:0      收藏:0      [点我收藏+]

 

 

题意:给一棵树,每个节点都有权值,要求选择部分节点出来,使得权值之和最大,但是每对(父亲,儿子)中最多只能挑一个。

 

思路:

  比较入门的题,每个节点可以选也可以不选。若当前节点选的话,孩子必须全部不选;若当前节点不选,则孩子可以选也可以不选。

 

 

技术分享
 1 #include <bits/stdc++.h>
 2 #define pii pair<int,int>
 3 #define INF 0x3f3f3f3f
 4 #define LL long long
 5 using namespace std;
 6 const int N=7010;
 7 int w[N], dp[N][2], pre[N];
 8 vector<int> tree[N];
 9 
10 void DFS(int t)
11 {
12     for(int i=0; i<tree[t].size(); i++)    DFS(tree[t][i]);
13     int sum[2]={0,0};
14     for(int i=0; i<tree[t].size(); i++)
15     {
16         sum[0]+=max(dp[tree[t][i]][0], dp[tree[t][i]][1]); //点t尝试不取,则孩子可以取也可以不取,取大者即可。
17         sum[1]+=max(dp[tree[t][i]][0], 0);    //点t尝试取,则孩子必须全部不取
18     }
19     dp[t][0]=sum[0];
20     dp[t][1]=sum[1]+w[t];
21 }
22 
23 
24 int main()
25 {
26     //freopen("input.txt", "r", stdin);
27     int n, a, b, root;
28     while(cin>>n)
29     {
30         memset(pre,0,sizeof(pre));
31         memset(dp,0,sizeof(dp));
32         for(int i=0; i<=n; i++) tree[i].clear();
33 
34         for(int i=1; i<=n; i++) scanf("%d",&w[i]);
35         while(scanf("%d%d",&a,&b),a+b)
36         {
37             tree[b].push_back(a);
38             pre[a]=b;
39         }
40         for(int i=1; i<=n; i++) if(pre[i]==0)   root=i;
41         DFS(root);
42         printf("%d\n", max(dp[root][0],dp[root][1]) );
43     }
44     return 0;
45 }
AC代码

 

HDU 1520 Anniversary party (树形DP,入门)

原文:http://www.cnblogs.com/xcw0754/p/4806509.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!