P1122 最大子树和

思路:由于是一棵n节点,n-1边的图,所以必然没有环,那么从任何一个节点出发都必然达到另外一个节点。
如果子节点的dp大于0,那么父节点加上,否则砍掉(不加)
同时如果visit过了那就不用visit,总体复杂度为O(n)。
代码:

#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<sstream>
#include<string>
#include<string.h>
#include<iomanip>
#include<stdlib.h>
#include<map>
#include<queue>
#include<limits.h>
#include<climits>
#include<fstream>
#include<stack>
typedef long long ll;
using namespace std;
const int N = 16010;
int val[N];
vector<int> G[N];//存图
int dp[N];//每个节点的max值
bool vis[N];//是否经历
void dfs(int x)// x号节点
{
	vis[x] = true;
	dp[x] = val[x];
	for (int i = 0; i < G[x].size(); i++)
	{
		int v = G[x][i];//子节点
		if (vis[v])continue;
		if (!vis[v])dfs(v);//没有就跑一遍
		if (dp[v] > 0)dp[x] += dp[v];//如果ok那就加上
	}

}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	int n; cin >> n;
	for (int i = 1; i <= n; i++)cin >> val[i];
	for (int i = 1; i < n; i++)
	{
		int u, v; cin >> u >> v;
		G[u].push_back(v), G[v].push_back(u);
	}
	dfs(1);//任意一个节点都行
	int maxn = INT_MIN;
	for (int i = 1; i <= n; i++)maxn = max(maxn, dp[i]);
	cout << maxn;
	return 0;
}

posted on 2024-05-15 14:55  WHUStar  阅读(2)  评论(0编辑  收藏  举报