Cod sursa(job #1389948)

Utilizator crucerucalinCalin-Cristian Cruceru crucerucalin Data 16 martie 2015 19:05:43
Problema Coduri Huffman Scor 65
Compilator cpp Status done
Runda Arhiva educationala Marime 2.21 kb
#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, 2*val, codes, total_len);
    inorder(root->right, len + 1, 2*val + 1, 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;
}