1 // 树形DP CCPC网络赛 HDU5834 Magic boy Bi Luo with his excited tree
2 // 题意:n个点的树,每个节点有权值为正,只能用一次,每条边有负权,可以走多次,问从每个点出发的最大获益
3 // 思路:
4 // dp[i]: 从i点出发回到i点的最大值
5 // d[i][0] 从i点出发不回来的最大值
6 // d[i][1] 从i点出发取最大值的下一个点
7 // d[i][2] 从i点出发取次大值
8 // dfs1处理出这四个
9 // 然后,从1开始转移,分别DP求子节点从父亲转移过来的最大值,和从父亲出去不回来的最大值
10
11 #include <bits/stdc++.h>
12 using namespace std;
13 #define LL long long
14 const double inf = 123456789012345.0;
15 const LL MOD =100000000LL;
16 const int N =1e5+10;;
17 #define clc(a,b) memset(a,b,sizeof(a))
18 const double eps = 1e-7;
19 void fre() {freopen("in.txt","r",stdin);}
20 void freout() {freopen("out.txt","w",stdout);}
21 inline int read() {int x=0,f=1;char ch=getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch=getchar();}while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;}
22
23 vector<pair<int,int> > g[N];
24 int a[N],ans[N];
25 int dp[N],d[N][3];
26 void dfs1(int u,int f){
27 dp[u]=a[u];
28 for(int i=0;i<(int)g[u].size();i++){
29 int v=g[u][i].first;
30 int val=g[u][i].second;
31 if(v==f) continue;
32 dfs1(v,u);
33 dp[u]+=max(0,dp[v]-2*val);
34 }
35 d[u][0]=d[u][2]=a[u];
36 d[u][1]=-1;
37 for(int i=0;i<(int)g[u].size();i++){
38 int v=g[u][i].first;
39 int val=g[u][i].second;
40 if(v==f) continue;
41 int tem=dp[u]-max(0,dp[v]-2*val)+max(0,d[v][0]-val);//当前选择路径不回来的最大值
42 if(tem>d[u][0]){
43 d[u][2]=d[u][0];
44 d[u][0]=tem;
45 d[u][1]=i;
46 }
47 else if(tem>d[u][2]){
48 d[u][2]=tem;
49 }
50 }
51 }
52
53 //no从父亲不回来的最大值,yes从父亲回来的最大值
54 void dfs2(int u,int f,int no,int yes){
55 ans[u]=max(dp[u]+no,yes+d[u][0]);
56 for(int i=0;i<(int)g[u].size();i++){
57 int v=g[u][i].first;
58 int val=g[u][i].second;
59 if(v==f) continue;
60 int tem1,tem2;
61 if(i==d[u][1]) tem1=max(0,d[u][2]-max(0,dp[v]-2*val));//从父亲出去但不是最优方案的最大值
62 else tem1=max(0,d[u][0]-max(0,dp[v]-2*val));
63 tem2=max(0,dp[u]-max(0,dp[v]-2*val));//从父亲出去又回来的最大值
64 tem1=max(0,max(tem1+yes-val,tem2+no-val));//儿子节点从父亲转移过来的是 max(父亲儿子节点出去不回来+父亲的父亲出去回来的最大值,父亲儿子节点出去回来+父亲的父亲出去不回来的最大值)
65 tem2=max(0,yes+tem2-2*val);
66 dfs2(v,u,tem1,tem2);
67 }
68 }
69
70 int main(){
71 int T;
72 scanf("%d",&T);
73 for(int cas=1;cas<=T;cas++){
74 int n;
75 scanf("%d",&n);
76 for(int i=1;i<=n;i++) g[i].clear();
77 for(int i=1;i<=n;i++) scanf("%d",&a[i]);
78 for(int i=1;i<n;i++){
79 int u,v,x;
80 scanf("%d%d%d",&u,&v,&x);
81 g[u].push_back(make_pair(v,x));
82 g[v].push_back(make_pair(u,x));
83 }
84 dfs1(1,-1);
85 dfs2(1,-1,0,0);
86 printf("Case #%d:\n",cas);
87 for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
88 }
89 return 0;
90 }