[UOJ 130]【NOI2015】荷马史诗:哈夫曼树

点击这里查看原题

二叉哈夫曼树教程:http://blog.csdn.net/shuangde800/article/details/7341289
这里是k叉哈夫曼树,依然采取贪心策略,不过需要注意的是首先要判断(n-1)%(k-1)是否为0,不为0则要添加权值为0的节点直到(n-1)%(k-1)=0
这是因为,每次合并操作会取出k个点,放进1个点,即每次减少k-1个点。而最终目标是使n个点变为1个点,因此需要用(n-1)%(k-1)来判断

/*
User:Small
Language:C++
Problem No.:130
*/
#include<bits/stdc++.h>
#define ll long long
#define inf ((ll)1<<60)
#define pli pair<ll,int>
#define mp make_pair
using namespace std;
int n,k,nn;
ll ans; 
priority_queue<pli,vector<pli>,greater<pli> > q;
int main(){
    freopen("data.in","r",stdin);//
    ios::sync_with_stdio(false);
    cin>>n>>k;
    nn=n;
    for(int i=1;i<=n;i++){
        ll x;
        cin>>x;
        q.push(mp(x,0));
    }
    if((n-1)%(k-1)) nn+=(k-1)-(n-1)%(k-1);
    for(int i=n+1;i<=nn;i++) q.push(mp(0,0));
    while(nn!=1){
        ll tot=0;
        int fl=0;
        for(int j=1;j<=k;j++){
            pli now=q.top();
            q.pop();
            tot+=now.first;
            fl=max(fl,now.second+1);
        }
        ans+=tot;
        q.push(mp(tot,fl));
        nn-=k-1;
    }
    pli fir=q.top();
    cout<<ans<<endl<<fir.second<<endl;
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章