欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > 蓝桥杯 9.生命之树

蓝桥杯 9.生命之树

2025/4/29 21:42:18 来源:https://blog.csdn.net/wuqingshun314159/article/details/147563422  浏览:    关键词:蓝桥杯 9.生命之树

生命之树

原题目链接

题目描述

在 X 森林里,上帝创建了生命之树。

他给每棵树的每个节点(叶子也称为一个节点)上,都标了一个整数,代表这个点的和谐值。

上帝要在这棵树内选出一个节点集 S,使得对于 S 中任意两个点 a, b,都存在一个点列:

a, v1, v2, …, vk, b

使得这个点列中的每个点都是 S 里面的元素,且序列中相邻两个点之间有一条边相连。

在这个前提下,上帝希望 S 中所有节点的整数和尽量大。

这个最大的和就是上帝给生命之树的评分。

注意:集合 S 可以为空。


输入描述

  • 第一行一个整数 n,表示这棵树有 n 个节点。
  • 第二行 n 个整数,依次表示每个节点的评分。
  • 接下来 n-1 行,每行两个整数 u, v,表示存在一条 u 到 v 的边。

保证:

  • 1 <= n <= 100000
  • 每个节点的评分的绝对值不超过 1000000

输出描述

输出一行一个整数,表示上帝给这棵树的最大评分。


输入输出样例

输入

5
1 -2 -3 4 5
4 2
3 1
1 2
2 5

输出

8

c++代码

#include<bits/stdc++.h>
#include<stdio.h>using namespace std;typedef long long ll;ll n, a, b, ans = 0;
vector<ll> trees, dp, know;
vector<vector<ll>> edges;void dfs(ll root) {know[root] = 0;dp[root] += trees[root];for (ll x : edges[root]) {if (!know[x]) continue;dfs(x);if (dp[x] > 0) dp[root] += dp[x];}ans = max(ans, dp[root]);
}int main() {scanf("%lld", &n);edges = vector<vector<ll>>(n + 1);trees = vector<ll>(n + 1, 0), dp = vector<ll>(n + 1, 0), know = vector<ll>(n + 1, 1);for (ll i = 1; i <= n; i++) scanf("%lld", &trees[i]);for (ll i = 0; i < n - 1; i++) {scanf("%lld %lld", &a, &b);edges[a].push_back(b);edges[b].push_back(a);}dfs(1);cout << ans;return 0;
}//by wqs

思路解析

题目的意思就是要我们找一颗子树,使得这颗子树的权值和最大。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词