Cod sursa(job #1997232)

Utilizator FlameingoAiordachioaei Marius Flameingo Data 3 iulie 2017 18:28:39
Problema Coduri Huffman Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.38 kb
#include<cstdio>
#include<queue>

const int NMAX = 1000002;
using namespace std;

class node
{
public:
    node(const long long value) : left(nullptr), right(nullptr)
    {
        this->value = value;
    }
    node *left, *right;
    long long value;
};

class leaf_node: public node
{
public:
    leaf_node(const long long val, const int sym) : node(val)
    {
        this->symbol = sym;
    }
    int symbol;
};

struct predicate
{
    bool operator () (const node *left, const node *right)
    {
        return left->value > right->value;
    }
};

int N;
queue<node*> Q;
queue<leaf_node*> lQ;

int len[NMAX];
unsigned long long code[NMAX];

int depth;
unsigned long long ans_sum;
void dfs(node* current, unsigned long long path = 0)
{
    if (current->left == nullptr && current->right == nullptr)
    {
        int sym = ((leaf_node*)current)->symbol;
        len[sym] = depth;
        code[sym] = path;
        return;
    }
    ans_sum += current->value;
    if (current->left != nullptr) {
        ++depth;
        dfs(current->left, path * 2);
        --depth;
    }
    if (current->right != nullptr) {
        ++depth;
        dfs(current->right, path * 2 + 1);
        --depth;
    }
}

node* pop_min ()
{
    node* ans;
    if (lQ.empty()) {
        ans = Q.front();
        Q.pop();
        return ans;
    }
    if (Q.empty()) {
        ans = lQ.front();
        lQ.pop();
        return ans;
    }
    node* lqf = lQ.front();
    node* qf = Q.front();
    if (lqf->value <= qf->value)
    {
        lQ.pop();
        return lqf;
    }
    else
    {
        Q.pop();
        return qf;
    }
}

int main()
{
    freopen("huffman.in", "r", stdin);
    freopen("huffman.out", "w", stdout);
    int val;

    scanf("%d", &N);
    for (int i = 0; i < N; ++i)
    {
        int val;
        scanf("%d", &val);
        leaf_node* leaf = new leaf_node(val ,i);
        lQ.push(leaf);
    }
    while(!lQ.empty() || Q.size() != 1)
    {
        node* first = pop_min();
        node* second = pop_min();

        node* parent = new node(first->value + second->value);
        parent->left = first;
        parent->right = second;

        Q.push(parent);
    }

    dfs(Q.front());
    printf("%llu\n", ans_sum);
    for (int i = 0; i < N; ++i) {
        printf("%d %llu\n", len[i], code[i]);
    }

}