樹形dp入門


POJ2342

一棵樹,每個節點有權值,兒子與父親不能同時取,求解從樹上選取點能獲得的最大權值

dp[i][0]表示不取,dp[i][1]表示取。

設j為i的兒子節點,dp[i][0] += max(dp[j][0], dp[j][1]),  dp[i][1] += dp[j][0];

 

入度為零的點是根,從根開始進行深搜。

 

 1 #include <vector>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 typedef long long LL;
 6 
 7 const int maxn = 6e3 + 10;
 8 int N;
 9 int dp[maxn][2];
10 bool in[maxn];
11 vector<int> tr[maxn];
12 
13 void dfs(int u) {
14     for (int i = 0; i < tr[u].size(); i++) {
15         int v = tr[u][i];
16         dfs(v);
17         dp[u][1] += dp[v][0];
18         dp[u][0] += max(dp[v][1], dp[v][0]);
19     }
20 }
21 
22 int main() {
23     while (~scanf("%d", &N)) {
24         memset(in, 0, sizeof(in));
25         memset(dp, 0, sizeof(dp));
26         for (int i = 0; i <= N; i++) tr[i].clear();
27         for (int i = 1; i <= N; i++) scanf("%d", &dp[i][1]);
28         int root = 1;
29         int u, v;
30         while (scanf("%d%d", &u, &v), u + v) {
31             tr[v].push_back(u);
32             in[u] = 1;
33         }
34         for (int i = 1; i <= N; i++) if (in[i] == 0) 
35             root = i;
36         dfs(root);
37         printf("%d\n", max(dp[root][0], dp[root][1]));
38     }
39     return 0;
40 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM