點擊這裏查看原題
二叉哈夫曼樹教程: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;
}