题目:给你一棵树,每个节点都有权值,你可以实行下面操作
选一条包含1节点的子树,对所有点的权值+1或-1
问:实行多少次操作才能使得整棵树每个点权值都为0
分析:动态dp,dfs
样例:
Input
3
1 2
1 3
1 -1 1
Output
3
#include <iostream> #include <cstdio> #include <vector> #include <cstdlib> using namespace std; #define MAXN 100050 #define LL long long vector<int> mp[MAXN]; LL dp[MAXN][2]; LL w[MAXN]; void dfs(int now,int pre) { LL maxi=0,maxd=0; for(unsigned int i = 0;i<mp[now].size();i++) { if(mp[now][i] == pre) continue; dfs(mp[now][i],now); maxi = max(maxi,dp[mp[now][i]][1]); maxd = max(maxd,dp[mp[now][i]][0]); } w[now] +=maxi; w[now] -=maxd; dp[now][1]=maxi; dp[now][0]=maxd; if(w[now]>0) dp[now][0]+=w[now]; else dp[now][1]+= (-w[now]); } int main() { int n; cin >> n; LL x,y; for(int i = 1 ; i < n; i++) { cin >> x >> y; mp[x].push_back(y); mp[y].push_back(x); } for(int i = 1;i<=n;i++) { cin >> w[i]; } dfs(1,0); cout << dp[1][0]+dp[1][1]<<endl; return 0; }