题目大意:
每个节点都给定一个值a[i],从一个节点走到另一个节点会消耗固定值w,但也会得到这个节点的价值,问怎样走才能得到最大的价值。
解题思路:
这个题和树形dp求树的直径差不多(树形DP基本都是相通的),f[X] 代表以x点为根节点,到子树叶子点可以获得的最大权值
Code:
#include <iostream>
#include <cstdio>
#include<cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#define inf 9654234
#define ll long long
using namespace std;
const int maxn=300007;vector<pair<ll,ll>> ve[maxn];
ll a[maxn],f[maxn],ans=0;void dfs(int u,int fa){f[u]=a[u];ans=max(ans,f[u]); //到子树可能获得的值为负数,那么就不去了for(auto v:ve[u]){int x=v.first;int y=v.second;if(x==fa) continue;dfs(x,u);ans=max(ans,f[u]+f[x]-y); // f[x]-y 是到达子树可以获得的最大权值,f[u]是从另一条边过来可以获得的最大权值f[u]=max(f[u],a[u]+f[x]-y); //更新f[u]的值}
}int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int n;cin>>n;for(int i=1;i<=n;i++) cin>>f[i];for(int i=1;i<n;i++){int u,v,w;cin>>u>>v>>w;ve[u].push_back(make_pair(v,w));ve[v].push_back(make_pair(u,w));}dfs(1,0);cout<<ans<<"\n";return 0;
}