Cod sursa(job #3133110)

Utilizator IsaacAvramescu Isaac Sebastian Isaac Data 25 mai 2023 09:07:11
Problema Coduri Huffman Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.4 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;

struct Node {
    int symbol;
    long long frequency;
    Node* left;
    Node* right;

    Node(int symbol, long long frequency) : symbol(symbol), frequency(frequency), left(nullptr), right(nullptr) {}
};

struct CompareNodes {
    bool operator()(const Node* a, const Node* b) const {
        return a->frequency > b->frequency;
    }
};

void generateHuffmanCodes(Node* root, const string& codePrefix, vector<pair<int, string>>& huffmanCodes) {
    if (root->left == nullptr && root->right == nullptr) {
        huffmanCodes.emplace_back(root->symbol, codePrefix);
        return;
    }

    generateHuffmanCodes(root->left, codePrefix + "0", huffmanCodes);
    generateHuffmanCodes(root->right, codePrefix + "1", huffmanCodes);
}

long long huffmanEncoding(const vector<long long>& frequencies, vector<pair<int, string>>& huffmanCodes) {
    priority_queue<Node*, vector<Node*>, CompareNodes> pq;

    for (int i = 0; i < frequencies.size(); i++) {
        if (frequencies[i] > 0) {
            pq.push(new Node(i, frequencies[i]));
        }
    }

    while (pq.size() > 1) {
        Node* leftChild = pq.top();
        pq.pop();
        Node* rightChild = pq.top();
        pq.pop();

        Node* internalNode = new Node(-1, leftChild->frequency + rightChild->frequency);
        internalNode->left = leftChild;
        internalNode->right = rightChild;

        pq.push(internalNode);
    }

    Node* root = pq.top();
    pq.pop();

    generateHuffmanCodes(root, "", huffmanCodes);

    long long encodedLength = 0;
    for (const auto& code : huffmanCodes) {
        encodedLength += frequencies[code.first] * code.second.length();
    }

    return encodedLength;
}

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

    int n;
    fin >> n;

    vector<long long> frequencies(n);
    for (int i = 0; i < n; i++) {
        fin >> frequencies[i];
    }

    vector<pair<int, string>> huffmanCodes;
    long long encodedLength = huffmanEncoding(frequencies, huffmanCodes);

    fout << encodedLength << "\n";
    for (const auto& code : huffmanCodes) {
        fout << code.second.length() << " " << code.second << "\n";
    }

    fin.close();
    fout.close();

    return 0;
}