Cod sursa(job #596466)

Utilizator dushmiMihai-Alexandru Dusmanu dushmi Data 17 iunie 2011 13:50:32
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.44 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

ifstream in("huffman.in");
ofstream out("huffman.out");

const int N = 2 * 1000005;

int n, maxlvl, nrn, niv[N];

long long tot, val[N], orig[N];

queue <int> Q1, Q2;

vector <int> L[N];

void read() {
    in >> n;

    for (int i = 1; i <= n; ++i) {
        in >> orig[i];
        Q1.push(i);
    }
}

void make_trie() {
    int x, y;
    nrn = n;

    while ((Q1.size() > 1 || Q2.size() > 1) || (Q1.size() == 1 && Q2.size() == 1)) {
        if (Q1.empty()) {
            x = Q2.front();
            Q2.pop();

            y = Q2.front();
            Q2.pop();
        } else if(Q2.empty()) {
            x = Q1.front();
            Q1.pop();

            y = Q1.front();
            Q1.pop();
        } else {
            if (orig[Q1.front()] > orig[Q2.front()]) {
                x = Q2.front();
                Q2.pop();
            } else {
                x = Q1.front();
                Q1.pop();
            }

            if (Q1.empty()) {
                y = Q2.front();
                Q2.pop();
            } else if (Q2.empty()) {
                y = Q1.front();
                Q1.pop();
            } else {
                if (orig[Q1.front()] > orig[Q2.front()]) {
                    y = Q2.front();
                    Q2.pop();
                } else {
                    y = Q1.front();
                    Q1.pop();
                }
            }
        }

        ++ nrn;

        L[nrn].push_back(x);
        L[nrn].push_back(y);

        Q2.push(nrn);

        orig[nrn] = orig[x] + orig[y];

        tot += orig[nrn];
    }

    out << tot << '\n';
}

void solve(int nod, long long valc, int lvl) {
    val[nod] = valc;

    niv[nod] = lvl;

    if (L[nod].empty())
        return;

    solve(L[nod][0], valc, lvl + 1);
    solve(L[nod][1], valc + ((long long)1 << (maxlvl - 1 - lvl)), lvl + 1);
}

void compute_maxlvl(int nod, int lvl) {
    if (lvl > maxlvl)
        maxlvl = lvl;

    if (L[nod].empty())
        return;

    compute_maxlvl(L[nod][0], lvl + 1);
    compute_maxlvl(L[nod][1], lvl + 1);
}

void afis() {
    for (int i = 1; i <= n; ++ i)
        out << niv[i] << ' ' << val[i] / ((long long)1 << (maxlvl - niv[i])) << '\n';
}

int main() {
    read();

    make_trie();

    compute_maxlvl(nrn, 0);

    solve(nrn, 0, 0);

    afis();

    return 0;
}