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的子节点)(子节点必须选)
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 }