HDU 5834 Magic boy Bi Luo with his excited tree 树形dp

题意 : 每个节点有一个价值Vi,每走一次一条边要花费Ci,问从各个节点出发最多能收获多少价值


同computer那道题一样也是维护三个值...虽然比较奇怪.....
维护的是从每个点回来的最大值,不回来的次大值,不回来的最大值....
细节还挺多的,没看题解的时候对数据的综合处理部分很头痛...需要一定的代码能力...我还是太蒻了...
原题解部分在第二次dfs中对数据的综合处理部分变量设置得很巧妙...避免了我开始代码那种绕来绕去好多if最后完全找不到关系的情况...非常值得借鉴...
果然还是不要脑补手推图比较靠谱... ...
顺便一提...我这道题看错了三次题目...重新写了三次...语文能力简直max...最后还是看题解中的题目介绍才明白
AC代码如下
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<queue>
  7 using namespace std;
  8 const int maxn=100010;
  9 int n,m,T;
 10 struct nod{
 11     int y;
 12     int v;
 13     int next;
 14 }e[maxn*2]={};
 15 int tot=0,head[maxn]={};
 16 int f[maxn][3]={};//012 回来 不回来最大 不回来次大
 17 int id[maxn]={};
 18 int ma[maxn]={};
 19 int c[maxn]={};
 20 inline void init(int x,int y,int v){
 21     e[++tot].y=y;
 22     e[tot].v=v;
 23     e[tot].next=head[x];
 24     head[x]=tot;
 25 }
 26 inline void yu(){
 27     tot=0;
 28     memset(id,0,sizeof(id));
 29     memset(head,0,sizeof(head));
 30     memset(ma,0,sizeof(ma));
 31     memset(f,0,sizeof(f));
 32 }
 33 void dfs1(int x,int fa){
 34     int y,v;
 35     f[x][1]=c[x];
 36     f[x][2]=c[x];
 37     f[x][0]=c[x];
 38     int t1;
 39     for(int i=head[x];i;i=e[i].next){
 40         y=e[i].y;
 41         v=e[i].v;
 42         if(y!=fa){
 43             dfs1(y,x);
 44             if(f[y][0]-v*2>0){
 45                 f[x][0]+=f[y][0]-v*2;
 46             }
 47         }
 48     }for(int i=head[x];i;i=e[i].next){
 49         y=e[i].y;
 50         v=e[i].v;
 51         if(y!=fa){
 52             t1=f[x][0]-max(0,f[y][0]-v*2)+max(0,f[y][1]-v);
 53             if(t1>f[x][1]){
 54                 f[x][2]=f[x][1];
 55                 f[x][1]=t1;
 56                 id[x]=y;
 57             }
 58             else if(t1>f[x][2]){
 59                 f[x][2]=t1;
 60             }
 61         }
 62     }
 63 }
 64 void dfs2(int x,int fa,int up1,int up2){
 65     int y,v;
 66     int t1,t2;
 67     ma[x]=max(up1+f[x][0],up2+f[x][1]);
 68     for(int i=head[x];i;i=e[i].next){
 69         y=e[i].y;
 70         v=e[i].v;
 71         t1=0,t2=0;//不回来 回来 
 72         if(y!=fa){
 73             if(id[x]==y){
 74                 t1=max(0,f[x][2]-max(0,f[y][0]-v*2));
 75             }
 76             else{
 77                 t1=max(0,f[x][1]-max(0,f[y][0]-v*2));
 78             }
 79             t2=max(0,f[x][0]-max(0,f[y][0]-v*2));
 80             t1=max(0,max(t1+up2,t2+up1)-v);
 81             t2=max(0,t2+up2-v*2);
 82             dfs2(y,x,t1,t2);
 83         }
 84     }
 85 }
 86 int main(){
 87     scanf("%d",&T);
 88     int t=0;
 89     while(T-->0){
 90         t++;
 91         yu();
 92         scanf("%d",&n);
 93         int x,v,y;
 94         for(int i=1;i<=n;i++){
 95             scanf("%d",&c[i]);
 96         }for(int i=1;i<n;i++){
 97             scanf("%d%d%d",&x,&y,&v);
 98             init(x,y,v);
 99             init(y,x,v);
100         }dfs1(1,0);
101         dfs2(1,0,0,0);
102         printf("Case #%d:\n",t);
103         for(int i=1;i<=n;i++){
104             printf("%d\n",ma[i]);
105         }
106     }
107 }
View Code

 

posted @ 2017-11-04 17:14  鲸头鹳  阅读(186)  评论(0编辑  收藏  举报