NewCodeTemplate
This commit is contained in:
76
模板/树/Huffman.cpp
Normal file
76
模板/树/Huffman.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
/*
|
||||
Huffman 树节点
|
||||
在竞赛中一般不需要真的建树,只关心权值
|
||||
*/
|
||||
struct Node {
|
||||
long long w; // 当前节点权值
|
||||
|
||||
Node(long long _w) : w(_w) {}
|
||||
};
|
||||
|
||||
/*
|
||||
priority_queue 默认是大根堆
|
||||
这里通过重载比较函数,使其变为小根堆
|
||||
*/
|
||||
struct cmp {
|
||||
bool operator()(const Node& a, const Node& b) const {
|
||||
return a.w > b.w; // 权值小的优先
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
ios::sync_with_stdio(false);
|
||||
cin.tie(nullptr);
|
||||
|
||||
int n;
|
||||
cin >> n;
|
||||
|
||||
/*
|
||||
优先队列(小根堆)
|
||||
每次可以 O(log n) 取出最小的两个权值
|
||||
*/
|
||||
priority_queue<Node, vector<Node>, cmp> pq;
|
||||
|
||||
// 读入 n 个权值
|
||||
for (int i = 0; i < n; i++) {
|
||||
long long x;
|
||||
cin >> x;
|
||||
pq.push(Node(x));
|
||||
}
|
||||
|
||||
/*
|
||||
特判:只有一个节点
|
||||
WPL = 0(没有边)
|
||||
*/
|
||||
if (n == 1) {
|
||||
cout << 0 << '\n';
|
||||
return 0;
|
||||
}
|
||||
|
||||
long long WPL = 0;
|
||||
|
||||
/*
|
||||
Huffman 树构造过程
|
||||
每次取最小的两个合并
|
||||
*/
|
||||
while (pq.size() > 1) {
|
||||
Node a = pq.top(); pq.pop();
|
||||
Node b = pq.top(); pq.pop();
|
||||
|
||||
long long mergedWeight = a.w + b.w;
|
||||
WPL += mergedWeight;
|
||||
|
||||
pq.push(Node(mergedWeight));
|
||||
}
|
||||
|
||||
// 输出带权路径长度
|
||||
cout << WPL << '\n';
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user