最大权值子树

题目链接

好烦好烦好烦,看不到未来在哪里,这么简单的题都不会做,蓝桥这种水赛省三都拼尽全力无法战胜,我怎么这么笨

求最大权值子树,每个点都在子节点里选大于0的加上去,最后加上本身,再返回父节点

void dfs(int now)
{
	res[now]=value[now];
	for(int i=head[now];i;i=edge[i].nxt)
	{
		int to=edge[i].to;
		if(vis[to]) continue;
		vis[to]=1;
		dfs(to);
		res[now]+=max(res[to],0ll);
	}
	ans=max(ans,res[now]);
}

不一定根节点就是最大,max每个点

允许不选任何节点,最大值可能是负数,用max

#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5+10,MOD=1e9+7;
LL n,ans,cnt,head[N],res[N],vis[N],value[N];
struct Edge{
	int to=0,nxt=0;
}edge[N<<1];

void add(int f,int t)
{
	edge[++cnt].nxt=head[f];
	edge[cnt].to=t;
	head[f]=cnt;
}

void dfs(int now)
{
	res[now]=value[now];
	for(int i=head[now];i;i=edge[i].nxt)
	{
		int to=edge[i].to;
		if(vis[to]) continue;
		vis[to]=1;
		dfs(to);
		res[now]+=max(res[to],0ll);
	}
	ans=max(ans,res[now]);
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++) cin>>value[i];
	for(int i=1;i<=n-1;i++)
	{
		int x,y;
		cin>>x>>y;
		add(x,y),add(y,x);
	}
	vis[1]=1;
	dfs(1);
	
	cout<<max(0ll,ans);
	return 0;
}
posted @ 2025-03-23 19:54  石磨豆浆  阅读(11)  评论(0)    收藏  举报