bzoj4198 [Noi2015]荷马史诗

题意:k叉哈夫曼树
题解:2叉哈夫曼树的做法我们知道后,k叉哈夫曼树就是每次找前k小的。但是现在的问题是可能有非满叉结点。考虑到非满叉结点一定是在最后一层,所以只需要补x个0即可。推一推知道是x = k - 1 - (n - 1) % (k - 1)。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct Node{
    ll val;
    int dep;

};
priority_queue< Node > q;
bool operator < (const Node &a,const Node &b){
    return a.val > b.val || (a.val == b.val && a.dep > b.dep);
}
int n,k,d;
Node nw;
ll tot,x,ans;
int main(){
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; i++){
        scanf("%lld", &x);
        q.push((Node){x, 1});
    }
    int rem = 0;
    if((n - 1) % (k - 1)){
        rem = k - 1 - (n - 1) % (k - 1);
        n += rem;
    }
    for(int i = 1; i <= rem; i++)
        q.push((Node){0, 1});
    /*for(int i = 1; i <= n; i++){
        nw = q.top();
        printf("%lld ", nw.val);
        q.pop();
    }*/
    n = (n - 1) / (k - 1);
    for(int i = 1; i <= n; i++){
        tot = 0;d = 0;
        for(int j = 1; j <= k; j++){
            nw = q.top();
            tot += nw.val;
            d = max(d, nw.dep);
            q.pop();
        }
        q.push((Node){tot, d + 1});
        ans += tot;

    }
    printf("%lld\n%d\n", ans, q.top().dep - 1);
    return 0;
}
发布了87 篇原创文章 · 获赞 7 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/yxr0105/article/details/78564772
今日推荐