1. 程式人生 > >HDU5834-Magic boy Bi Luo with his excited tree

HDU5834-Magic boy Bi Luo with his excited tree


題解:
f[u][0/1]表示u往下走,回/不回到u獲得的最大價值
此題要求以每個點為起點的答案,那麼還可能往父親走
再令g[u][0/1]表示u往父親走,回/不回到u獲得的最大價值
f[u][1]=max(f[u][1],f[u][1]+f[v][0]2len(u>v))
f[u][1]=max(f[u][1],f[u][0]+f[v][1]len(

u>v))
f[u][0]=max(f[u][0],f[u][0]+f[v][0]2len(u>v))
dfs一次求完f後,再dfsg
g要考慮兩種情況
一、走到u的父親後繼續向上走,比較好處理
二、走到u的父親後向其他子樹走,
此時不能再走向u,所以要記錄f[x][1]的次大值
且計算時減去走向u產生的價值
Code

#include<bits/stdc++.h>
#define N 100005
using namespace std;
int tot,u[N
],v[2*N],w[2*N],pre[2*N],q[N],fa[N],g1[N],g[N][2],f[N][2]; void add(int x,int y,int z) { v[tot]=y;w[tot]=z;pre[tot]=u[x];u[x]=tot++; v[tot]=x;w[tot]=z;pre[tot]=u[y];u[y]=tot++; } void dfs1(int x,int y) { g[x][0]=g[x][1]=q[x];g1[x]=x;fa[x]=y; for(int i=u[x];i!=-1;i=pre[i]) if(v[i]!=y)
{ dfs1(v[i],x); g[x][1]=max(g[x][1],g[x][1]+g[v[i]][0]-2*w[i]); if(g[x][0]+g[v[i]][1]-w[i]>g[x][1]) g1[x]=v[i]; g[x][1]=max(g[x][1],g[x][0]+g[v[i]][1]-w[i]); g[x][0]+=max(0,g[v[i]][0]-2*w[i]); } } void dfs2(int x,int y,int z) { f[x][0]=f[x][1]=0; if(g[x][0]<=2*z) { f[x][0]=max(f[x][0],f[y][0]+g[y][0]-2*z); f[x][1]=max(f[x][1],f[y][1]+g[y][0]-z); }else { f[x][0]=max(f[x][0],f[y][0]+g[y][0]-g[x][0]); f[x][1]=max(f[x][1],f[y][1]+g[y][0]-g[x][0]+z); } if(g1[y]==x) { int i,mx0=q[y],mx1=q[y]; for(i=u[y];i!=-1;i=pre[i]) if(v[i]!=fa[y]&&v[i]!=x) { mx1=max(mx1,mx1+g[v[i]][0]-2*w[i]); mx1=max(mx1,mx0+g[v[i]][1]-w[i]); mx0+=max(0,g[v[i]][0]-2*w[i]); } f[x][1]=max(f[x][1],mx1+f[y][0]-z); }else { if(g[x][0]<=2*z)f[x][1]=max(f[x][1],f[y][0]+g[y][1]-z); else f[x][1]=max(f[x][1],f[y][0]+g[y][1]-g[x][0]+z); } for(int i=u[x];i!=-1;i=pre[i]) if(v[i]!=y)dfs2(v[i],x,w[i]); } int main() { int i,n,t,x,y,z,ca; scanf("%d",&t); f[0][0]=f[0][0]=0; g[0][0]=g[0][1]=0; for(ca=1;ca<=t;ca++) { scanf("%d",&n); tot=0;memset(u,-1,sizeof(u)); for (i=1;i<=n;i++) scanf("%d", &q[i]); for (i=1;i<n;i++) scanf("%d%d%d", &x, &y, &z),add(x,y,z); dfs1(1,0);dfs2(1,0,0); printf("Case #%d:\n", ca); for (i=1;i<=n;i++) printf("%d\n", max(g[i][0]+f[i][1],g[i][1]+f[i][0])); } return 0; }