D. The Omnipotent Monster Killer

 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;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值