CodeForces 274B Zero Tree :每次选包含1节点的一棵子树,将该子树所有值都+1或者-1最少多少步可以使树值全部为0 :树型dp
将1设为树根节点,接下来就好想了,因为更新一个点对应到1的路全部都要更新
对于一个节点u,dfs他的所有儿子节点,返回最大需要+1的操作和最大需要-1的操作
再接合自身返回给父亲节点+1 -1的最大操作
最后结果就是1节点+1和-1的最大操作和
1 #include<stdio.h> 2 #include<string.h> 3 #include<math.h> 4 #include<vector> 5 #include<algorithm> 6 using namespace std; 7 #define LL long long 8 vector<LL>G[100005]; 9 LL up[100005],down[100005],val[100005]; 10 void dfs(LL u,LL pre) 11 { 12 LL s=0,d=0; 13 for (LL i=0;i<G[u].size();i++) 14 { 15 if (G[u][i]==pre) continue; 16 dfs(G[u][i],u); 17 s=max(s,up[G[u][i]]); 18 d=max(d,down[G[u][i]]); 19 } 20 val[u]=val[u]+s-d; 21 up[u]=s; down[u]=d; 22 if (val[u]<0) up[u]=up[u]+(-val[u]); 23 else down[u]=down[u]+val[u]; 24 } 25 int main() 26 { 27 LL n,i,x,y; 28 scanf("%I64d",&n); 29 for (i=1;i<=n;i++) G[i].clear(); 30 for (i=1;i<n;i++) 31 { 32 scanf("%I64d%I64d",&x,&y); 33 G[x].push_back(y); 34 G[y].push_back(x); 35 } 36 for (i=1;i<=n;i++) scanf("%I64d",&val[i]); 37 dfs(1,0); 38 printf("%I64d\n",down[1]+up[1]); 39 }