马上就是小苗的生日了,为了给小苗准备礼物,小葱兴冲冲地来到了商店街。商店街有n个商店,并且它们之间的道路构成了一颗树的形状。
第i个商店只卖第i种物品,小苗对于这种物品的喜爱度是wi,物品的价格为ci,物品的库存是di。但是商店街有一项奇怪的规定:如果在商店u,v买了东西,并且有一个商店w在u到v的路径上,那么必须要在商店w买东西。小葱身上有m元钱,他想要尽量让小苗开心,所以他希望最大化小苗对买
到物品的喜爱度之和。这种小问题对于小葱来说当然不在话下,但是他的身边没有电脑,于是他打电话给同为OI选手的你,你能帮帮他吗?
输入第一行一个正整数T,表示测试数据组数。
对于每组数据,
第一行两个正整数n;m;
第二行n个非负整数w1,w2...wn;
第三行n个正整数c1,c2...cn;
第四行n个正整数d1,d2...dn;
接下来n-1行每行两个正整数u;v表示u和v之间有一条道路
输出共T 行,每行一个整数,表示最大的喜爱度之和。
1 #include<cstdio>
2 #include<cstring>
3 #include<algorithm>
4 typedef long long lnt;
5 const int N=510;
6 const int M=4010;
7 struct pnt{
8 int hd;
9 int wgt;
10 int w;
11 int c;
12 int d;
13 int ind;
14 int oud;
15 bool vis;
16 }p[N],stp;
17 struct ent{
18 int twd;
19 int lst;
20 }e[N<<1];
21 int T,n,m;
22 int cnt;
23 int dfn;
24 int size;
25 int root;
26 int maxsize;
27 lnt ans;
28 int lin[N];
29 lnt dp[N][M];
30 void ade(int f,int t)
31 {
32 cnt++;
33 e[cnt].twd=t;
34 e[cnt].lst=p[f].hd;
35 p[f].hd=cnt;
36 return ;
37 }
38 void grc_dfs(int x,int f)
39 {
40 p[x].wgt=1;
41 int maxs=-1;
42 for(int i=p[x].hd;i;i=e[i].lst)
43 {
44 int to=e[i].twd;
45 if(to==f||p[to].vis)
46 continue;
47 grc_dfs(to,x);
48 p[x].wgt+=p[to].wgt;
49 if(maxs<p[to].wgt)
50 maxs=p[to].wgt;
51 }
52 maxs=std::max(maxs,size-p[x].wgt);
53 if(maxs<maxsize)
54 {
55 root=x;
56 maxsize=maxs;
57 }
58 return ;
59 }
60 void Build_dfs(int x,int f)
61 {
62 lin[++dfn]=x;
63 p[x].ind=dfn;
64 for(int i=p[x].hd;i;i=e[i].lst)
65 {
66 int to=e[i].twd;
67 if(to==f||p[to].vis)
68 continue;
69 Build_dfs(to,x);
70 }
71 p[x].oud=dfn;
72 return ;
73 }
74 void bin_dfs(int x)
75 {
76 p[x].vis=true;
77 dfn=0;
78 Build_dfs(x,x);
79 for(int i=0;i<=dfn+1;i++)
80 for(int j=0;j<=m;j++)
81 dp[i][j]=0;
82 for(int i=dfn;i;i--)
83 {
84 int t=lin[i];
85 int w=p[t].d-1;
86 for(int j=m;j>=p[t].c;j--)
87 dp[i][j]=dp[i+1][j-p[t].c]+p[t].w;
88 for(int j=1;;j<<=1)
89 {
90 if(w<j)
91 j=w;
92 for(int k=m;k>=j*p[t].c;k--)
93 dp[i][k]=std::max(dp[i][k],dp[i][k-j*p[t].c]+j*p[t].w);
94 w-=j;
95 if(!w)
96 break;
97 }
98 for(int j=0;j<=m;j++)
99 dp[i][j]=std::max(dp[i][j],dp[p[t].oud+1][j]);
100 }
101 ans=std::max(ans,dp[1][m]);
102 for(int i=p[x].hd;i;i=e[i].lst)
103 {
104 int to=e[i].twd;
105 if(p[to].vis)
106 continue;
107 root=0;
108 size=p[to].wgt;
109 maxsize=0x3f3f3f3f;
110 grc_dfs(to,to);
111 bin_dfs(root);
112 }
113 return ;
114 }
115 int main()
116 {
117 //freopen("a.in","r",stdin);
118 scanf("%d",&T);
119 while(T--)
120 {
121 scanf("%d%d",&n,&m);
122 for(int i=1;i<=n;i++)
123 p[i]=stp;
124 cnt=0,ans=0;
125 for(int i=1;i<=n;i++)
126 scanf("%d",&p[i].w);
127 for(int i=1;i<=n;i++)
128 scanf("%d",&p[i].c);
129 for(int i=1;i<=n;i++)
130 scanf("%d",&p[i].d);
131 for(int i=1;i<n;i++)
132 {
133 int a,b;
134 scanf("%d%d",&a,&b);
135 ade(a,b);
136 ade(b,a);
137 }
138 root=0;
139 size=n;
140 maxsize=0x3f3f3f3f;
141 grc_dfs(1,1);
142 bin_dfs(root);
143 printf("%lld\n",ans);
144 }
145 return 0;
146 }