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 }