Codeforces Round #384 (Div. 2) D. Chloe and pleasant prizes(树形DP)

题目链接
在这里插入图片描述
在这里插入图片描述
思路:有点和求树上的最大子段和差不多,但略有不同,因为cut了一条边以后它的所有子树和都要算进去,我们设dp【i】为i的子树中子树的sum和最大的,之后遍历i的子节点,每次选最大的两个来cut,记录答案取max。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+1;
const ll inf=1e18;
ll ans=-inf,dp[maxn],a[maxn],sum[maxn],max1,max2;
vector<int>g[maxn];
void dfs(int u,int fa)
{
	sum[u]=a[u];
	ll max1=-inf,max2=-inf;
	for(int to:g[u])
	{
		if(to==fa) continue;
		dfs(to,u);
		sum[u]+=sum[to];
	}
	dp[u]=sum[u];
	for(int to:g[u])
	{
		if(to==fa) continue;
		dp[u]=max(dp[u],dp[to]);
	}
	for(int to:g[u])
	{
		if(to==fa) continue;
		if(dp[to]>max1) max2=max1,max1=dp[to];
		else if(dp[to]>max2) max2=dp[to];
	}
	if(max2!=-inf) ans=max(ans,max1+max2);
}
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
	for(int i=1,u,v;i<n;++i)
	{
		scanf("%d%d",&u,&v);
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs(1,0);
	if(ans>-inf) printf("%lld\n",ans);
	else printf("Impossible\n");
}
发布了171 篇原创文章 · 获赞 0 · 访问量 5792

猜你喜欢

转载自blog.csdn.net/qq_42479630/article/details/104640422