HDU 1520 Anniversary party (树形DP)

http://acm.hdu.edu.cn/showproblem.php?pid=1520

题意:

给你一棵树,n节点,然后给你每个节点的权值,以及树的结构,要求不能同时选中父节点和它的直接子节点,让你找到权值最大的结果

简单的树形DP

dp[s][0]表示以s为根的子树在s点不选的情况下的最大权值

dp[s][1]表示以s为根的子树在s点选的情况下的最大权值

则:

dp[s][0]=sigma(max(dp[ss][0],dp[ss][1]))(ss表示s的子节点)(子节点可选可不选)

dp[s][1]=sigma(dp[ss][1])(ss表示s的子节点)(子节点必须选)

HDU 1520 Anniversary party (树形DP)
  1 #pragma comment(linker, "/STACK:102400000,102400000")
  2 #include <cstdio>
  3 #include <iostream>
  4 #include <cstring>
  5 #include <string>
  6 #include <cmath>
  7 #include <set>
  8 #include <list>
  9 #include <map>
 10 #include <iterator>
 11 #include <cstdlib>
 12 #include <vector>
 13 #include <queue>
 14 #include <stack>
 15 #include <algorithm>
 16 #include <functional>
 17 using namespace std;
 18 typedef long long LL;
 19 #define ROUND(x) round(x)
 20 #define FLOOR(x) floor(x)
 21 #define CEIL(x) ceil(x)
 22 const int maxn = 6010;
 23 const int maxm = 13010;
 24 const int inf = 0x3f3f3f3f;
 25 const LL inf64 = 0x3f3f3f3f3f3f3f3fLL;
 26 const double INF = 1e30;
 27 const double eps = 1e-6;
 28 const int P[4] = {0, 0, -1, 1};
 29 const int Q[4] = {1, -1, 0, 0};
 30 const int PP[8] = { -1, -1, -1, 0, 0, 1, 1, 1};
 31 const int QQ[8] = { -1, 0, 1, -1, 1, -1, 0, 1};
 32 
 33 int n;
 34 int dp[maxn][2];
 35 int root;
 36 int fa[maxn];
 37 struct Edge
 38 {
 39     int u, v;
 40     int next;
 41 } edge[maxm];
 42 int en;
 43 int head[maxn];
 44 bool vis[maxn];
 45 int node[maxn];
 46 void addsubedge(int u, int v)
 47 {
 48     edge[en].u = u;
 49     edge[en].v = v;
 50     edge[en].next = head[u];
 51     head[u] = en++;
 52 }
 53 void addedge(int u, int v)
 54 {
 55     addsubedge(u, v);
 56     addsubedge(v, u);
 57 }
 58 void init()
 59 {
 60     memset(head, -1, sizeof(head));
 61     memset(dp, 0x3f, sizeof(dp));
 62     en = 0;
 63     memset(vis, 0, sizeof(vis));
 64     memset(fa, -1, sizeof(fa));
 65 }
 66 void input()
 67 {
 68     for (int i = 1; i <= n; i++) scanf("%d", &node[i]);
 69     int u, v;
 70     while (~scanf("%d%d", &u, &v))
 71     {
 72         if (!u && !v) return;
 73         addedge(u, v);
 74         fa[u] = v;
 75     }
 76 }
 77 void dfs(int s)
 78 {
 79     vis[s] = 1;
 80     dp[s][1] = node[s];
 81     dp[s][0] = 0;
 82     for (int i = head[s]; i != -1; i = edge[i].next)
 83     {
 84         int v = edge[i].v;
 85         if (vis[v]) continue;
 86         dfs(v);
 87         dp[s][0] += max(dp[v][1], dp[v][0]);
 88         dp[s][1] += dp[v][0];
 89     }
 90 }
 91 void debug()
 92 {
 93     //
 94 }
 95 void solve()
 96 {
 97     root = 1;
 98     while (fa[root] != -1) root = fa[root];
 99     dfs(root);
100 }
101 void output()
102 {
103     printf("%d\n", max(dp[root][0], dp[root][1]));
104 }
105 int main()
106 {
107     // std::ios_base::sync_with_stdio(false);
108 #ifndef ONLINE_JUDGE
109     freopen("in.cpp", "r", stdin);
110 #endif
111 
112     while (~scanf("%d", &n))
113     {
114         init();
115         input();
116         solve();
117         output();
118     }
119     return 0;
120 }
View Code

HDU 1520 Anniversary party (树形DP)

上一篇:size_t 类型


下一篇:快速填充像素的方法