Question meaning: Given a spanning tree, each point has a weight, which represents the price of the product, and each edge on the tree also has a weight, which represents the cost of passing through this edge. Now you need to choose two points on the tree, one as the point of buying the commodity, and one as the point of selling the commodity, of course, you need to consider the cost of passing the edge from the buy point to the sell point. maximize profit. The buy point and sell point are allowed to coincide, that is, the minimum profit is 0.
This question can be asked without tree DP, which is really clever. post someone else's solution
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int MAXN = 500010;
const int INF = 2000;
typedef struct node {
int from;
int to;
int value;
int next;
}node;
node edge[MAXN];
int head[MAXN], cnt, n;
int d[MAXN], vis[MAXN];
void addedge(int from, int to, int value) {
edge[cnt].from = from;
edge[cnt].to = to;
edge[cnt].value = value;
edge[cnt].next = head[from];
head[from] = cnt++;
}
void spfa(int s, int e) {
queue<int> mq;
mq.push(s);
vis[s] = 1;
d[s] = 0;
while (!mq.empty()) {
int front = mq.front();
mq.pop();
vis[front] = 0;
for (int i = head[front]; i != -1; i = edge[i].next) {
int to = edge[i].to;
int value = edge[i].value;
if (d[to] < d[front] + value) {
d[to] = d[front] + value;
if (!vis[to]) {
mq.push(to);
vis[to] = 1;
}
}
}
}
}
int main(void) {
int t;
scanf("%d", &t);
while (t--) {
memset(head, -1, sizeof(head));
cnt = 0;
scanf("%d", &n);
int a, b, c;
for (int i = 1; i <= n; i++) {
scanf("%d", &b);
addedge(0, i, -b);
addedge(i, n + 1, b);
}
for (int i = 1; i <= n - 1; i++) {
scanf("%d%d%d", &a, &b, &c);
addedge(a, b, -c);
addedge(b, a, -c);
}
memset(vis, 0, sizeof(vis));
for (int i = 0; i <= n + 1; i++)
d[i] = -INF;
spfa(0, n + 1);
printf("%d\n", d[n + 1]);
}
return 0;
}