hdu 1520 Anniversary party(树形dp)

题目链接

题意:

输入一个N,代表树的结点个数,接下来N行代表1到N节点的欢乐值,之后的若干行输入为L和K,表示L的父节点为K,求的是该树最大的欢乐值为多少,需注意的是父子节点不能同时出现。

分析:

用d[i][0] 表示节点i 不出现的最大欢乐值,d[i][0]表示节点i 出现的最大欢乐值。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cmath>
 6 #include <algorithm>
 7 #include <vector>
 8 #define LL __int64
 9 const int maxn = 6000+10;
10 using namespace std;
11 int a[maxn], head[maxn], d[maxn][2], ans, vis[maxn], t;
12 struct node
13 {
14     int u, v, to;
15 } e[2*maxn];
16 void add(int u, int v)
17 {
18     e[t].u = u;
19     e[t].v = v;
20     e[t].to = head[u];
21     head[u] = t++;
22 }
23 void dfs(int u)
24 {
25     int i, v;
26 
27     vis[u] = 1;
28     for(i = head[u]; i != -1; i = e[i].to)
29     {
30         v = e[i].v;
31         if(vis[v]) continue;
32         dfs(v);
33         d[u][1] += d[v][0];
34         d[u][0] += max(d[v][0], d[v][1]);
35     }
36 }
37 
38 int main()
39 {
40     int i, n, l, k;
41     while(~scanf("%d", &n))
42     {
43         for(i = 1; i <= n; i++)
44         {
45             scanf("%d", &a[i]);
46             d[i][0] = 0;
47             d[i][1] = a[i];
48         }
49         t = 0;
50         memset(head, -1, sizeof(head));
51         memset(vis, 0, sizeof(vis));
52 
53         while(~scanf("%d%d", &l, &k))
54         {
55             if(l==0 && k==0) break;
56             add(k, l);
57             add(l, k);
58         }
59         dfs(1);
60         ans = max(d[1][0], d[1][1]);
61         cout<<ans<<endl;
62     }
63     return 0;
64 }
原文地址:https://www.cnblogs.com/bfshm/p/3974838.html