Cod sursa(job #2908557)

Utilizator BeilandArnoldArnold Beiland BeilandArnold Data 4 iunie 2022 12:30:22
Problema Coduri Huffman Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.01 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <set>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;

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

vector<nod> noduri;
vector<int> code_lengths;
vector<long long> code_values;

long long dfs(int in, int depth, long long cod)
{
    const nod &curr = noduri[in];
    if (curr.left == -1) {
        code_lengths[in] = depth;
        code_values[in] = cod;
        return (long long) depth * curr.weight;
    }
    else {
        return dfs(curr.left, depth+1, cod << 1)
            + dfs(curr.right, depth+1, (cod << 1) + 1);
    }
}

int select(queue<int> &q1, queue<int> &q2)
{
    int rez;

    if (q1.size() == 0) {
        rez = q2.front();
        q2.pop();
    }
    else if (q2.size() == 0) {
        rez = q1.front();
        q1.pop();
    }
    else if (noduri[q1.front()].weight < noduri[q2.front()].weight) {
        rez = q1.front();
        q1.pop();
    }
    else {
        rez = q2.front();
        q2.pop();
    }

    return rez;
}

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

    int n;
    fin >> n;

    noduri.resize(n);
    code_lengths.resize(n);
    code_values.resize(n);

    //priority_queue<nod*, deque<nod*>, MyComparison> pq;
    queue<int> before, after;

    for (int i = 0; i < n; ++i) {
        nod a;
        a.left = a.right = -1;
        fin >> a.weight;

        noduri[i] = a;
        before.push(i);
    }

    while (before.size() > 0 || after.size() > 1) {
        int in1 = select(before, after);
        int in2 = select(before, after);

        nod nou;
        nou.weight = noduri[in1].weight + noduri[in2].weight;
        nou.left = in1;
        nou.right = in2;

        noduri.push_back(nou);
        after.push(noduri.size() - 1);
    }

    int iroot = after.front();

    long long total = dfs(iroot, 0, 0);

    fout << total << "\n";

    for (int i = 0; i < n; ++i) {
        fout << code_lengths[i] << " " << code_values[i] << "\n";
    }

    return 0;
}