Pagini recente » Cod sursa (job #2097585) | Cod sursa (job #261982) | Cod sursa (job #790466) | Cod sursa (job #509827) | Cod sursa (job #1307884)
#include <cstdint>
#include <algorithm>
#include <fstream>
#include <queue>
#include <vector>
#include <memory>
#include <map>
using namespace std;
struct Node;
typedef shared_ptr<Node> node_t;
struct Node {
uint64_t w;
node_t left;
node_t right;
Node(uint64_t w, node_t left = nullptr, node_t right = nullptr)
: w {w}, left {left}, right {right}
{}
};
uint64_t df(node_t node, map<int, vector<uint64_t>>& alph, uint64_t rep = 0, int h = 0) {
while (node->left && node->right)
return df(node->left, alph, rep << 1, h + 1) +
df(node->right, alph, (rep << 1) + 1, h + 1);
alph[h].push_back(rep);
return h * node->w;
}
inline
node_t pop(queue<node_t>& Q_leaf, queue<node_t>& Q_internal) {
node_t r;
if (Q_leaf.size()) {
if (Q_internal.size()) {
if (Q_leaf.front()->w < Q_internal.front()->w) {
r = Q_leaf.front();
Q_leaf.pop();
}
else {
r = Q_internal.front();
Q_internal.pop();
}
}
else {
r = Q_leaf.front();
Q_leaf.pop();
}
}
else {
r = Q_internal.front();
Q_internal.pop();
}
return r;
}
int main() {
ifstream fin("huffman.in");
ofstream fout("huffman.out");
int n; fin >> n;
// min priority queue
queue<node_t> Q_leaf, Q_internal;
for (uint64_t x; n--;) {
fin >> x;
Q_leaf.push(make_shared<Node>(x));
}
// build Huffman tree
while (Q_leaf.size() + Q_internal.size() > 1) {
node_t l = pop(Q_leaf, Q_internal),
r = pop(Q_leaf, Q_internal);
Q_internal.push(make_shared<Node>(l->w + r->w, l, r));
}
map<int, vector<uint64_t>> alph;
fout << df(Q_internal.front(), alph) << '\n';
for (auto it = alph.rbegin(); it != alph.rend(); ++it)
for (auto rep : it->second)
fout << (it->first) << ' ' << rep << '\n';
return 0;
}