[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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章