给定的图有 n 个节点,n-1 条边,这个图是一棵树。
任意一个节点都可以作为根节点,先处理叶子节点在处理上一层,这样处理下来就是一次后序dfs过程了(任意一个节点都可以作为dfs的开始)。
对于每个节点来说,有一个最优买入价格(分为两种情况,1:从该节点的所有子树(指直接子树 孙子节点不算)中挑一个最优买入价格+该路径代价(指u-v这条路径代价),2:从自己这里买),
举个例子,设父节点为 u ,直接子树的根节点为 v,那么 u 的最优买入价格= 所有的 v 的最优买入价格 + 路径代价(u-v这条路径)(有多颗子树,路径代价(u-v)不相同)
类似的,每个节点还有一个最优的卖出价格(也分为两种情况,1:从该节点的所有子树中挑一个最优卖出价格 - 该路径代价(u-v),2:从自己这里卖)
注意这里是减路径代价,然后每个节点的最优路线价格为 = 该节点的最优买入价格 + 该节点的最优卖出价格,在 所有 的节点中取最大值即可,因为不一定在根节点取到最大值。
每个节点的maxback表示该节点的最优买入价格,初始值为负的该节点的书价格(即从自己这里买书的花费)。
maxgo表示该节点最优卖出价格,初始值为该节点的书的价格(即从自己这里卖书的价格)。
maxback+maxgo=该节点的最优路线价格。
这里说明一下这一段代码:
maxback=max(maxback,op.first-t.va);//可以这样理解,maxback为买书赚的钱(当然是负的,取最大值是指负的最少)
maxgo=max(maxgo,op.second-t.va);//maxgo为卖书赚的钱(取最大值是指赚的最多)。
ac代码:
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int T,n;
int price[100005];
typedef pair<int,int> pii;
typedef struct node {
int pi;
int va;
}node;
vector<node> mp[100005];
bool visit[100005];
int ans;
pii dfs(int p) {
visit[p]=1;
int maxback=-price[p],maxgo=price[p];
for(int i=0;i<mp[p].size();i++) {
node t=mp[p][i];
if(!visit[t.pi]) {
pii op=dfs(t.pi);
maxback=max(maxback,op.first-t.va);
maxgo=max(maxgo,op.second-t.va);
}
}
ans=max(ans,maxback+maxgo);
return pii(maxback,maxgo);
}
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
memset(visit,0,sizeof(visit));
for(int i=1;i<=n;i++) {
mp[i].clear();
scanf("%d",&price[i]);
}
for(int i=1;i<=n-1;i++) {
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
mp[a].push_back(node{b,c});
mp[b].push_back(node{a,c});
}
ans=0;
dfs(1);
printf("%d\n",ans);
}
return 0;
}