bzoj4198 [Noi2015]荷马史诗 k叉哈夫曼树

本文介绍了一种构建k叉哈夫曼树的方法,通过添加w值为0的节点确保最终树中每个节点都有k个子节点或为叶子节点。使用优先级队列进行节点合并,以实现O(nlogn)的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

k叉哈夫曼树
二叉就是贪心,找最小的两个合并,想当年记得是用。。两个数组存的吧。。只是tooyoungtoosimple。。虽然是O(n),优先级队列O(nlogn)。。
k叉的是添加x个w值为0节点,使得最后组成的是每个节点要么是叶子,要么是有k个儿子,数学(?)推导一下即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
#define ll long long
using namespace std;
struct node{
    ll val;int len;
    bool operator < (const node &x)const{
        return x.val<val||(x.val==val&&x.len<len);
    }
};
int n,k,anslen=0;ll ansval=0;
priority_queue<node>huff;
int main(){
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        ll x;
        scanf("%lld",&x);
        huff.push((node){(ll)x,1});
    }
    int t=(((n-1)/(k-1)+1)*(k-1)+1-n)%(k-1);
    for(int i=1;i<=t;i++) huff.push((node){(ll)0,1});
    while(!huff.empty()){
        int len=0;ll val=0;
        for(int i=1;i<=k;i++){
            node x=huff.top();
            huff.pop();
            val+=x.val;len=max(len,x.len);
        }
        if(!huff.empty()) {
            len++;
            huff.push((node){(ll)val,len});
        }
        ansval+=val;anslen=len;
    }
    printf("%lld\n%d\n",ansval,anslen);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值