Cod sursa(job #2765576)

Utilizator Mihai_BarbuMihai Barbu Mihai_Barbu Data 27 iulie 2021 23:40:01
Problema Coduri Huffman Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.65 kb
#include <bits/stdc++.h>

std::ifstream fin("huffman.in");
std::ofstream fout("huffman.out");

#define ll long long

const int NMAX = 2e6 + 2;

// no. symbols == no. leaves
int N;

// freq[i] = frequency of the i-th symbol
ll freq[NMAX], val[NMAX];
int l[NMAX], r[NMAX], h[NMAX];

std::queue<int> q_k; // keys
std::queue<int> q_int; // interior nodes

ll res;

int get_min() {
    int min;

    if (q_k.empty()) {
        min = q_int.front();
        q_int.pop();

        return min;
    }

    if (q_int.empty()) {
        min = q_k.front();
        q_k.pop();

        return min;
    }

    if (freq[q_k.front()] <= freq[q_int.front()]) {
        min = q_k.front();
        q_k.pop();
    } else {
        min = q_int.front();
        q_int.pop();
    }

    return min;
}

void replace_nodes(int x, int y, int z) {
    freq[z] = 0LL + freq[x] + freq[y];
    q_int.push(z);
    
    res += freq[z];

    l[z] = x;
    r[z] = y;
}

void parse_tree(int curr) {
    // check for leaf
    if (l[curr]) {
        h[l[curr]] = h[curr] + 1;
        h[r[curr]] = h[curr] + 1;

        val[l[curr]] = 2 * val[curr];
        val[r[curr]] = 2 * val[curr] + 1;

        parse_tree(l[curr]);
        parse_tree(r[curr]);
    }
}

int main() {
    fin >> N;

    int i;
    for (i = 1; i <= N; ++i) {
        fin >> freq[i];
        q_k.push(i);
    }

    int x, y;
    int z = N;
    // until root is reached
    while (q_k.size() + q_int.size() > 1) {
        x = get_min();
        y = get_min();

        ++z;
        replace_nodes(x, y, z);
    }

    fout << res << "\n";

    parse_tree(z);

    for (i = 1; i <= N; ++i) {
        fout << h[i] << " " << val[i] << "\n";
    }

    return 0;
}