题意:从任意一点买书,到任意一点卖书,询问赚的钱最多为多少
思路:
对于每一个节点维护出两个值:
1.在这个点买需要多少钱 -A[i]
2.在这个点卖多少钱A【i】
这样维护到树的顶点,必定得出了任意两点差价最大的值
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn=200000;
ll a[maxn];
ll minn[maxn];
ll maxx[maxn];
ll ans;
vector<pair<int,ll > >vec[maxn];
void dfs(int u,int f)
{
minn[u]=-a[u],maxx[u]=a[u];
for(int i=0;i<vec[u].size();i++)
{
int v=vec[u][i].first;
ll w=vec[u][i].second;
if(f==v) continue;
dfs(v,u);
minn[u]=max(minn[u],minn[v]-w);
maxx[u]=max(maxx[u],maxx[v]-w);
}
ans=max(ans,maxx[u]+minn[u]);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=1;i<=n;i++)
vec[i].clear();
ans=0;
for(int i=1;i<n;i++)
{
int x,y;
ll w;
scanf("%d%d%lld",&x,&y,&w);
vec[x].push_back(make_pair(y,w));
vec[y].push_back(make_pair(x,w));
}
dfs(1,1);
printf("%lld\n",ans);
}
}