解题思路:
定义dp[i],代表该子树中最大的一条链(由叶子到根),注意到有可能叶子的权全是复数,所以我们把res初始化为负无穷。
核心代码:
void dfs(int u,int f)
{
dp[u]=w[u];
for(auto to:e[u])
{
if(to==f) continue;
dfs(to,u);
res=max(res,dp[u]+dp[to]);//两个子树合并
dp[u]=max(dp[u],w[u]+dp[to]);//选一个最大的子树
}
res=max(res,dp[u]);
}
在搜索的过程中,搜到一个点时,合并两个子树,并且求出其中最大的结果,res取所有结果中的最大值,最后即可求出答案。在顺序遍历子树的过程中更新dp[u],同时每次更新res
完整代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
vector<int> e[maxn];
long long dp[maxn],w[maxn];
long long res=-0x3f3f3f3f3f3f;
void dfs(int u,int f)
{
dp[u]=w[u];
for(auto to:e[u])
{
if(to==f) continue;
dfs(to,u);
res=max(res,dp[u]+dp[to]);
dp[u]=max(dp[u],w[u]+dp[to]);
}
res=max(res,dp[u]);
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;++i)
cin>>w[i];
for(int i=0;i<n-1;++i)
{
int x,y;
cin>>x>>y;
e[x].push_back(y);
e[y].push_back(x);
}
dfs(1,0);
cout<<res<<endl;
return 0;
}