树形dp mark

A - Anniversary party HDU - 1520 

题意是 有一个树 每个点都有一个价值,选了父亲节点就不能选子节点 选了子节点就不能选父亲节点 

问最后能得到的最大价值是多少

树形dp入门  定义状态 dp[i][1]表示选中此节点 dp[i][0]表示未选中此节点

那么 dp[i][1]=sigma(dp[j][0])+a[i]; //j为i的儿子节点

dp[i][0]=sigma(max(dp[j][1],dp[j][0]))+a[i];

另外无论如何都要吐槽一下这题的输入格式!!!!

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n;
 4 const int maxn=6060;
 5 
 6 vector<int>G[maxn];
 7 int v[6060];
 8 int dp[maxn][2];
 9 int pre[maxn];
10 
11 int dfs(int x)
12 {
13     dp[x][1]=v[x];
14     for(int i=0;i<G[x].size();i++)
15         dfs(G[x][i]);
16     for(int i=0;i<G[x].size();i++)
17     {
18         dp[x][1]+=dp[G[x][i]][0];
19         dp[x][0]+=max(dp[G[x][i]][1],dp[G[x][i]][0]);
20     }
21 }
22 
23 int main()
24 {
25     int x,y;
26     while(~scanf("%d",&n)){
27     for(int i=0;i<=n;i++) G[i].clear();
28     for(int i=1;i<=n;i++) scanf("%d",&v[i]);
29     memset(pre,-1,sizeof(pre));
30     while(~scanf("%d%d",&x,&y))
31     {
32         if(x==0||y==0) break;
33         G[y].push_back(x);
34         pre[x]=y;
35     }
36 
37     memset(dp,0,sizeof(dp));
38 
39     int root=1;
40     while(pre[root]!=-1) root=pre[root];
41     dfs(root);
42     printf("%d\n",max(dp[root][0],dp[root][1]));
43 }
44 }

 

B - Computer

 HDU - 2196 

给一个树 求每个节点能够到达的最远距离是多少?

定义dp[i][0]为i节点向下走的最远距离,自下而上

dp[i][1]为i节点向下走的次远距离,自下而上

dp[i][2]为i节点向上走的最远距离,自上而下

那么每一个节点能够到达的最远距离与 儿子节点到达的距离有关 与父亲节点到达的距离有关

那么就需要两次dfs , 第一次自下而上 维护一个 dp[i][0],dp[i][1],

第二次dfs 自上而下 维护一下 dp[i][2];

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef pair<int,int> pii;
 5 
 6 const int maxn=1e4+5;
 7 
 8 int n;
 9 vector<pii >G[maxn];
10 
11 int dp[maxn][3];
12 
13 int dfs1(int u)
14 {
15     for(int i=0;i<G[u].size();i++)
16     {
17         int v=G[u][i].first;
18         int w=G[u][i].second;
19         dfs1(v);
20         if(dp[u][0]<=dp[v][0]+w)
21         {
22             dp[u][1]=dp[u][0];
23             dp[u][0]=dp[v][0]+w;
24         }
25         else if(dp[v][0]+w>dp[u][1])
26             dp[u][1]=dp[v][0]+w;
27     }
28 }
29 
30 int dfs2(int u)
31 {
32     for(int i=0;i<G[u].size();i++)
33     {
34         int v=G[u][i].first;
35         int w=G[u][i].second;
36         if(dp[u][0]!=dp[v][0]+w)
37         {
38             dp[v][2]=max(dp[u][0]+w,dp[u][2]+w);
39         }
40         else{
41             dp[v][2]=max(dp[u][1]+w,dp[u][2]+w);
42         }
43         dfs2(v);
44     }
45 }
46 
47 int main()
48 {
49     int x,y;
50     while(~scanf("%d",&n))
51     {
52         for(int i=0;i<=n;i++) G[i].clear();
53         for(int i=2;i<n+1;i++)
54         {
55             scanf("%d%d",&x,&y);
56             G[x].push_back({i,y});
57         }
58 
59         memset(dp,0,sizeof(dp));
60 
61         dfs1(1);
62         dfs2(1);
63 
64         for(int i=1;i<=n;i++)
65             printf("%d\n",max(dp[i][0],dp[i][2]));
66     }
67 }

 

 

 

posted @ 2017-08-17 09:17  TomJarry  阅读(158)  评论(0编辑  收藏  举报