传送门:牛客
题目描述:
给定一棵树 T ,树 T 上每个点都有一个权值。
定义一颗树的子链的大小为:这个子链上所有结点的权值和 。
请在树 T 中找出一条最大的子链并输出。
输入:
5
2 -1 -1 -2 3
1 2
2 3
2 4
2 5
输出:
4
一道简单的树形dp的题目,但是有一些需要注意的点
主要思路:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define root 1,n,1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {
ll x=0,w=1;char ch=getchar();
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x*w;
}
#define maxn 1000000
#define ll_maxn 0x3f3f3f3f3f3f3f3f
const double eps=1e-8;
ll dp[maxn];int n;
vector<ll>tree[101000];
ll a[maxn];ll ans=-inf;
void dfs(int u,int pre_u) {
dp[u]=a[u];
for(int i=0;i<tree[u].size();i++) {
int v=tree[u][i];
if(v==pre_u) continue;
dfs(v,u);
ans=max(dp[u]+dp[v],ans);
dp[u]=max(dp[v]+a[u],dp[u]);
}
ans=max(dp[u],ans);
return ;
}
int main() {
n=read();
for(int i=1;i<=n;i++) {
a[i]=read();
}
int u,v;
for(int i=1;i<=n-1;i++) {
u=read();v=read();
tree[u].push_back(v);
tree[v].push_back(u);
}
dfs(1,-1);
// ll ans=-inf;//三十分的惨痛教训
// for(int i=1;i<=n;i++) {
// ans=max(ans,dp[i]);
// }
cout<<ans<<endl;
return 0;
}