点击这里查看原题
二叉哈夫曼树教程: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;
}