Cod sursa(job #2908546)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 4 iunie 2022 11:55:23
Problema Coduri Huffman Scor 65
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.03 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <set>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;

struct nod {
    int weight;
    int symbol;
    nod *left;
    nod *right;
};

struct stats {
    int length;
    long long value;
};


class MyComparison
{
    public:
        bool operator() (nod *const &lhs, nod *const &rhs) const
        {
            return lhs->weight > rhs->weight;
        }
};

bool compare_coduri(pair<nod*, stats> &r1, pair<nod*, stats> &r2)
{
    return r1.first->symbol < r2.first->symbol;
}


long long dfs(nod *n, int depth, long long cod, vector<pair<nod*, stats>> &coduri) {
    if (n == nullptr)
        return 0;
    else {
        if (n->left == nullptr) {
            stats s;
            s.length = depth;
            s.value = cod;
            coduri.push_back(make_pair(n, s));
            return (long long) depth * n->weight;
        }
        else {
            return dfs(n->left, depth+1, cod << 1, coduri)
                + dfs(n->right, depth+1, (cod << 1) + 1, coduri);
        }
    }
}

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

    int n;
    fin >> n;

    priority_queue<nod*, deque<nod*>, MyComparison> pq;

    for (int i = 0; i < n; ++i) {
        nod *a = new nod;
        a->symbol = i;
        a->left = a->right = nullptr;
        fin >> a->weight;

        pq.push(a);
    }

    while (pq.size() > 1) {
        nod *n1 = pq.top();
        pq.pop();
        nod *n2 = pq.top();
        pq.pop();

        nod *nou = new nod;
        nou->symbol = -1;
        nou->weight = n1->weight + n2->weight;
        nou->left = n1;
        nou->right = n2;

        pq.push(nou);
    }

    nod *root = pq.top();

    vector<pair<nod*, stats>> coduri;
    coduri.reserve(n);

    long long total = dfs(root, 0, 0, coduri);

    fout << total << "\n";

    sort(coduri.begin(), coduri.end(), compare_coduri);

    for (auto &cod : coduri) {
        fout << cod.second.length << " " << cod.second.value << "\n";
    }

    return 0;
}