#Z1890. 裁枝剪叶

题目

#Z1890. 裁枝剪叶_第1张图片


思路

 做这道题之前可以先看看:#B. 部落联盟_草原上有n个部落,每个部落都有其坐标(xi,yi) 每个部落都有个武力值,可正可负 由于-CSDN博客

 我们可以这么做:

设以x节点为根的子树的点权和最大值为dp[x]

那么在dfs遍历树的节点时

先将dp[x]设为x的点权

然后每枚举完x的一个儿子点后判断如果dp[son] > 0,则dp[x]+=dp[son]

否则dp[x]就不用动。

最后取dp[1~n]的最大值就行了

是不是觉得恍然大悟


代码

#include
#define int long long
using namespace std;
int n,u,v,d[100001],ans = -114514191810,dp[100001];
vector vec[1000001];
void dfs(int x,int fa)
{
  dp[x] = d[x];
  for(int i = 0;i < vec[x].size();i++)
    if(fa != vec[x][i])
    {
      dfs(vec[x][i],x);
      if(dp[vec[x][i]] > 0) dp[x] += dp[vec[x][i]];
    }
}
signed main()
{
  cin>>n;
  for(int i = 1;i <= n;i++) cin>>d[i];
  for(int i = 1;i < n;i++)
  {
    cin>>u>>v;
	  vec[u].push_back(v);
	  vec[v].push_back(u);
  }
  dfs(1,0);
  for(int i = 1;i <= n;i++) ans = max(ans,dp[i]);
  cout<

结语

如果对您有帮助的话,记得点个赞支持一下QwQ疯狂明示 

你可能感兴趣的:(算法)