Cod sursa(job #3222386)

Utilizator marinaoprOprea Marina marinaopr Data 9 aprilie 2024 22:09:57
Problema Coduri Huffman Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.05 kb

#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

int n;
vector<int> a;
vector<pair<short int, long long> > ans;

class Node {
    public:
        Node *left;
        Node *right;
        int freq;

        Node() {
            this->left = NULL;
            this->right = NULL;
            this->freq = 0;
        }

        Node(Node *left, Node *right) {
            this->left = left;
            this->right = right;
            this->freq = left->freq + right->freq;
        }

        ~Node() {}
};

class Leaf : public Node {
    public:
        int index;

        Leaf(int index) {
            Node();
            this->index = index;
            this->freq = a[index];
        }

        ~Leaf() {}
};

queue<Node *> initial;
queue<Node *> intern;

long long int dfs(Node *root, int niv, long long cod)
{
    if (!root->left && !root->right) {
        Leaf *leaf = (Leaf *)root;
        ans[leaf->index].first = niv;
        ans[leaf->index].second = cod;
        return 0LL;
    }

    long long ret = 1LL * root->freq;
    if (root->left) {
        ret += dfs(root->left, niv + 1, (cod << 1LL) | 0LL);
    }
    if (root->right) {
        ret += dfs(root->right, niv + 1, (cod << 1LL) | 1LL);
    }

    return ret;
}

int main()
{
    fin >> n;
    a.reserve(n);

    int x;
    for (int i = 0; i < n; i++) {
        fin >> x;
        a.push_back(x);
    }
    initial.push(new Leaf(0));
    initial.push(new Leaf(1));

    int index = 2;

    Node *min1 = NULL, *min2 = NULL;
    while (!initial.empty() || intern.size() != 1) {
        if (intern.empty()) {
            min1 = initial.front();
            initial.pop();
        } else
            if (initial.empty()) {
                min1 = intern.front();
                intern.pop();
            } else {
                if (initial.front()->freq < intern.front()->freq) {
                    min1 = initial.front();
                    initial.pop();
                } else {
                    min1 = intern.front();
                    intern.pop();
                }
            }
        
        if (intern.empty()) {
            min2 = initial.front();
            initial.pop();
        } else
            if (initial.empty()) {
                min2 = intern.front();
                intern.pop();
            } else {
                if (initial.front()->freq < intern.front()->freq) {
                    min2 = initial.front();
                    initial.pop();
                } else {
                    min2 = intern.front();
                    intern.pop();
                }
            }

        intern.push(new Node(min1, min2));
        while (initial.size() < 2 && index < n) {
            initial.push(new Leaf(index));
            index++;
        }
    }

    Node *root = intern.front();
    intern.pop();
    a.shrink_to_fit();
    ans.resize(n);
    
    fout << dfs(root, 0, 0LL) << "\n";

    for (int i = 0; i < n; i++)
        fout << ans[i].first << " " << ans[i].second << "\n";

    fin.close();
    fout.close();
    return 0;
}