树上子链(树形DP)

在这里插入图片描述
解题思路:
定义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;
}
发布了165 篇原创文章 · 获赞 11 · 访问量 4885

猜你喜欢

转载自blog.csdn.net/weixin_43784305/article/details/105096557
今日推荐