我也没发现哪里复杂度假了呀。
#include<bits/stdc++.h>
using namespace std;
const int maxn=3e5+5;
class edge{
public:
int to,nex;
edge(int to,int nex):to(to),nex(nex) {}
edge() {}
};
edge e[maxn<<1];
int head[maxn],tot;
inline void add_edge(int from,int to){
e[++tot]=edge(to,head[from]),head[from]=tot;
}
long long hit[maxn];
int fa[maxn],maxround;
inline void pre_work(int u,int father){
fa[u]=father;
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;
if(v!=father){
pre_work(v,u);
}
}
}
long long f[maxn][21];
inline void Solve(int u){
f[u][0]=0x7f7f7f7f7f7f7f7f;
long long sum=0;
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;
if(v!=fa[u]){
Solve(v);
int min_it=0,c_min_it=0;
for(int j=1;j<=maxround;++j){
if(f[v][j]<f[v][min_it]){
c_min_it=min_it;
min_it=j;
}
else if(f[v][j]<f[v][c_min_it]){
c_min_it=j;
}
}
f[u][min_it]+=f[v][c_min_it]-f[v][min_it];
sum+=f[v][min_it];
}
}
for(int i=1;i<=maxround;++i){
f[u][i]+=sum+hit[u]*i;
}
}
int main(){
//freopen("CF Round 958 D.in","r",stdin);
int T;
scanf("%d",&T);
while(T--){
memset(f,0,sizeof(f)),memset(head,0,sizeof(head)),tot=0;
int n;
scanf("%d",&n);
maxround=ceil(log2(n))+1;
for(int i=1;i<=n;++i){
scanf("%lld",&hit[i]);
}
for(int i=1;i<n;++i){
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v),add_edge(v,u);
}
pre_work(1,0);
Solve(1);
long long minn=0x7f7f7f7f7f7f7f7f;
for(int i=1;i<=maxround;++i){
minn=min(minn,f[1][i]);
}
printf("%lld\n",minn);
}
return 0;
}
O(n logn)