Cod sursa(job #3222345)

Utilizator marinaoprOprea Marina marinaopr Data 9 aprilie 2024 20:09:19
Problema Coduri Huffman Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.67 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<int, int> > ans;

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

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

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

        ~Node() {}
};

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

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

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

    return ret;
}

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

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

    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));
    }

    Node *root = intern.front();
    intern.pop();

    fout << dfs(root, 0, 0) << "\n";

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

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