Pagini recente » Cod sursa (job #1949372) | Cod sursa (job #1389929)
#include <iostream>
#include <fstream>
#include <queue>
#include <memory>
#include <cassert>
#include <algorithm>
struct Node
{
Node(int _w,
std::shared_ptr<Node> l = nullptr,
std::shared_ptr<Node> r = nullptr)
: weight(_w)
, left(l)
, right(r)
{}
int weight;
std::shared_ptr<Node> left;
std::shared_ptr<Node> right;
};
using VecOfLLPair = std::vector<std::pair<int, long long>>;
void inorder(const std::shared_ptr<Node> &root,
int len,
long long val,
VecOfLLPair &codes,
long long *total_len)
{
if (!root->left) {
assert(!root->right);
codes.emplace_back(len, val);
*total_len += 1LL * len * root->weight;
return;
}
inorder(root->left, len + 1, val, codes, total_len);
inorder(root->right, len + 1, val | (1 << len), codes, total_len);
}
VecOfLLPair get_codes(const std::shared_ptr<Node> &root, long long *len)
{
VecOfLLPair codes;
inorder(root, 0, 0LL, codes, len);
return codes;
}
int main()
{
std::ifstream fin{"huffman.in"};
std::ofstream fout{"huffman.out"};
auto pq_cmp = [](const std::shared_ptr<Node> &lhs,
const std::shared_ptr<Node> &rhs) {
return lhs->weight > rhs->weight;
};
std::priority_queue<
std::shared_ptr<Node>,
std::vector<std::shared_ptr<Node>>,
decltype(pq_cmp)
> pq(pq_cmp);
int N;
fin >> N;
for (auto i = 0; i < N; ++i) {
int weight;
fin >> weight;
pq.push(std::make_shared<Node>(weight));
}
while (pq.size() > 1) {
auto child1 = pq.top();
pq.pop();
auto child2 = pq.top();
pq.pop();
pq.push(std::make_shared<Node>(child1->weight + child2->weight,
child1, child2));
}
assert(pq.size() == 1);
auto len = 0LL;
auto codes = get_codes(pq.top(), &len);
std::sort(codes.begin(), codes.end(), std::greater<std::pair<int, long long>>());
fout << len << '\n';
for (auto &i : codes)
fout << i.first << ' ' << i.second << '\n';
return 0;
}