树形dp,求连接到节点1的子树,在合法操作下 需要多少步能整棵树节点变为0;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int maxn=100002;
typedef long long ll;
ll add[maxn],sub[maxn];
int n,val[maxn];
vector<int>Edge[maxn];
int dfs(int u,int fa)
{
int i,j;
add[u]=sub[u]=0;
for(i=0;i<Edge[u].size();++i)
{
int v=Edge[u][i];
if(v==fa)continue;
dfs(v,u);
add[u]=max(add[u],add[v]);
sub[u]=max(sub[u],sub[v]);
}
ll res=val[u]+add[u]-sub[u];
if(res>0)sub[u]+=res;
else add[u]-=res;
}
int main()
{
//freopen("D://input.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
int i,j,u,v;
for(i=1;i<=n;i++)Edge[i].clear();
for(i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
Edge[u].push_back(v);
Edge[v].push_back(u);
}
//memset(add,0,sizeof(int)*(n+1));
// memset(sub,0,sizeof(int)*(n+1));
for(i=1;i<=n;i++)scanf("%d",&val[i]);
dfs(1,-1);
cout<<add[1]+sub[1]<<endl;
}
return 0;
}