D. The Omnipotent Monster Killer
- 不每到一轮再考虑杀哪些,而是对怪物考虑,考虑怪物什么时候死,死前造成了多少伤害
- 不以轮数为考虑主体,而是以怪物为考虑主体
- 若当前根的怪物在wi轮死亡,wi没在之前出现过
- 则该根需要连接根为1,2,3……wi-1的树
- toti为根在i轮的树最少需要多少个节点,可以得出n个节点最大能成几轮
- tot1=1,tot2=1+1=2,tot3=1+2+1=4,tot4=1+2+4+1=8……toti=Sum { totj } + 1=2^i
- 所以有n个节点=2^i,i=log2n
- 所以最大次数为log2n
- f i j 以i为根,轮数为j
- 由于第i轮怪物先打
- f i j = ai * j + Sum{ min f v k }
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using pii = pair<int,int>;
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
// long long md=(long long)998244353;
// i64 mx=LONG_LONG_MAX/2;
int T;std::cin>>T;
for(;T>0;--T){
int n;std::cin>>n;
std::vector<i64> a(n+5);
for(int i=1;i<=n;++i)std::cin>>a[i];
std::vector<std::vector<int>> G(n+5);
for(int i=1;i<n;++i){
int u,v;std::cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
std::vector<std::vector<i64>> f(n+5,std::vector<i64>(22,0));
auto dfs=[&](auto &&dfs,int x,int p)->void{
for(int j=1;j<=21;++j) {
f[x][j] = a[x] * j;
}
for(auto v:G[x]){
if(v==p)continue;
dfs(dfs,v,x);
for(int j=1;j<=21;++j){
i64 mi=LONG_LONG_MAX/2;
for(int k=1;k<=21;++k){
if(k==j)continue;
mi=min(mi,f[v][k]);
}
f[x][j]+=mi;
}
}
};
dfs(dfs,1,0);
i64 ans=LONG_LONG_MAX/2;
for(int j=1;j<=21;++j)ans=min(ans,f[1][j]);
std::cout<<ans<<std::endl;
}
}