题解:P8625 [蓝桥杯 2015 省 B] 生命之树
题目大意
题目中讲到:_
这意味着
思路分析
算法:树形 dp。
我们不妨令
以 u 为根子树的最大连通权值和。
那么
解题步骤
- 用
a_i 存储每个节点的权值并读入树的边。 - 通过 dfs 遍历此树。
- 在 dfs 的同时进行对
dp 数组的计算。 - 遍历结束,在
dp_1...n 中找到最大值,输出。代码实现
#include<bits/stdc++.h>
#define int long long//一定要开
using namespace std;
const int N=1e5+7,inf=1e18;
int n,a[N],dp[N];//dp[u]以u节点为根其子树的最大连通权值
vector<int> g[N];
void dfs(int u,int fa){
dp[u]=a[u];//初始化 最大值是根节点的权
for(auto v:g[u]){
if(v==fa)continue ;
dfs(v,u);
dp[u]=max(dp[u],dp[u]+dp[v]);//状态转移 自己的最大值 和 自己加上子树的最大值 的较大值
}
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
//存入树边
}
dfs(1,-1);
int ans=0;//注意:s可以为空集 此处不能将ans赋值为负无穷大
for(int i=1;i<=n;i++)ans=max(ans,dp[i]);
cout<<ans;
return 0;
}
注:十年 OI 一场空,不开 long long 见祖宗