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 ",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 ",max(dp[i][0],dp[i][2])); 66 } 67 }