InputThe first line contains an integer TT (1≤T≤101≤T≤10) , the number of test cases.
For each test case:
first line contains an integer nn (2≤n≤1000002≤n≤100000) means the number of cities;
second line contains nn numbers, the iithth number means the prices in iithth city; (1≤Price≤10000)(1≤Price≤10000)
then follows n−1n−1 lines, each contains three numbers xx, yy and zz which means there exists a road between xx and yy, the distance is zzkmkm (1≤z≤1000)(1≤z≤1000).
OutputFor each test case, output a single number in a line: the maximum money he can get.
Sample Inputnode
1 4 10 40 15 30 1 2 30 1 3 2 3 4 10
Sample Outputc++
8
一我的在任意點買書(消費點權),通過邊(花費邊權),在任意點賣書(收穫點權),求最大收益。
樹形結構,由於父子關係未知,因此雙向建邊。
dp[i][0]表示i子樹中的最少買書消費,dp[i][1]表示i子樹中的最大賣書收益,
dp[i][0]+dp[i][1]表示以i爲最近公共父節點的最大收益,最優解並不是根節點,所以ans須要不斷更新。
#include<bits/stdc++.h> #define MAX 100005 #define INF 0x3f3f3f3f using namespace std; typedef long long ll; int a[MAX]; int dp[MAX][2]; int ans; struct Node{ int v,w; }node; vector<Node> v[MAX]; void dfs(int x,int pre){ dp[x][0]=-a[x];dp[x][1]=a[x]; for(int i=0;i<v[x].size();i++){ int to=v[x][i].v; if(to==pre) continue; int w=v[x][i].w; dfs(to,x); dp[x][0]=max(dp[x][0],dp[to][0]-w); dp[x][1]=max(dp[x][1],dp[to][1]-w); } ans=max(ans,dp[x][0]+dp[x][1]); //不斷更新 } int main() { int t,n,i; int x,y,w; scanf("%d",&t); while(t--){ scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%d",&a[i]); v[i].clear(); } for(i=1;i<n;i++){ scanf("%d%d%d",&x,&y,&w); node.v=y;node.w=w; v[x].push_back(node); node.v=x; v[y].push_back(node); } ans=-INF; dfs(1,-1); printf("%d\n",ans); } return 0; }