要求 合并k个的哈夫曼树并且取层数与树的带权路径长度和最小
思路 优先队列实现小根堆每个节点包括权值和层数。每次哈夫曼操作取最大层并将层数加一。
注意要点 首先叶节点是否排满可以插入0解决,当多个值相同时应选择最小层数;
代码如下
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, int> PLI;
int main(){
int n, k;
cin >> n >> k;
priority_queue<PLI, vector<PLI>, greater<PLI>> heap;
for(int i = 0;i < n;i++){
LL x;
cin >> x;
heap.push({x, 0});//从零层开始
}
while((n - 1) % (k - 1)) heap.push({0LL,0}), n ++;//若是不能整除就补零可以免去特判
LL res = 0;
while(heap.size() > 1){
LL sum = 0;
int depth = 0;
for(int i = 0;i < k;i ++){//这里小根堆以first为第一关键字second为第二关键字所以取层数最小的要求已被小根堆解决
auto x = heap.top();
sum += x.first;
heap.pop();
depth = max(depth,x.second);
}
heap.push({sum, depth + 1});//每次结合层数加一
res += sum;
}
cout << res << endl << heap.top().second << endl;
return 0;
}