题目
题解:这个题给了我们一个树,很明显这是一个树形dp,我们这样表示状态,dp[i]表示i的孩子以i为结尾的最大值,那么以i的这棵树上能取到的最大值就是以i为结尾的最大值和以i为结尾的次大值相加(就是以i为中间点)。我们用一个全局变量去更新这个值,但是dp[i]依旧存的是以i为结尾的最大值,如果你存以i为中间点的最大值,那么向上更新时当前dp[i]里存的已经是一条有开头有结尾的路径了,再往上更新会出错。
#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)
#define endl "\n"
using namespace std;
const int maxn = 3e5 + 5;
ll x[maxn], head[maxn * 2];
ll dp[maxn];
ll f[maxn];
int cnt;
ll ans = 0;
struct node
{
ll to, next, w;
} e[maxn * 2];
void add(int u,int v,int w)
{
e[++cnt] = {v, head[u], w};
head[u] = cnt;
}
void solve(int a,int fa)
{
dp[a] = x[a];
//cout << a << endl;
for (int i = head[a]; i;i=e[i].next)
{
int v = e[i].to;
if(v==fa) continue;
solve(v, a);
if(dp[v]<e[i].w)
continue;
ans = max(ans, dp[a] + dp[v] - e[i].w);
dp[a] = max(dp[a], dp[v] - e[i].w + x[a]);
}
}
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n;i++)
cin >> x[i], ans = max(ans, x[i]);
for (int i = 1; i < n;i++)
{
ll u, v, w;
cin >> u >> v >> w;
add(u, v, w);
add(v, u, w);
}
solve(1, 0);
cout << ans;
}