Cod sursa(job #2217875)

Utilizator nurof3nCioc Alex-Andrei nurof3n Data 2 iulie 2018 14:45:42
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.92 kb
#include <fstream>
#include <queue>

using namespace std;

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

const int MAXC = 1000001;
struct nod
{
    int left, right;
};
nod arb[MAXC * 2];

int N, lgcod[MAXC];
long long fr[MAXC * 2], cod[MAXC], lgtext;

queue<int> Q1; //contine nodurile initiale
queue<int> Q2; //contine nodurile interne

void rsd(int nod, int K, long long val)
{
    if(arb[nod].left)
    {
        rsd(arb[nod].left, K + 1, (val << 1LL));
        rsd(arb[nod].right, K + 1, (val << 1LL) + 1LL);
    }
    else
    {
        lgcod[nod] = K;
        cod[nod] = val;
    }
}
void get_fr(int &x)
{
    if (Q1.empty())
    {
        x = Q2.front();
        Q2.pop();
    }
    else if (Q2.empty())
    {
        x = Q1.front();
        Q1.pop();
    }
    else if (fr[Q1.front()] < fr[Q2.front()])
    {
        x = Q1.front();
        Q1.pop();
    }
    else
    {
        x = Q2.front();
        Q2.pop();
    }
}

void citire_frecv()
{
///FRECVENTELE SUNT IN ORDINE CRESCATOARE, DECI NU MAI AVEM NEVOIE DE HEAP, FOLOSIM QUEUE
    in >> N;
    int x;
    for(int i = 1; i <= N; i++)
    {
        in >> x;
        fr[i] = (long long) x;
        Q1.push(i);
    }
}
void Huffman()
{
    int nrnod = N;
    while(Q1.size() + Q2.size() >= 2)
    {
        int left, right;
        get_fr(left);
        get_fr(right);
        nrnod++;
        Q2.push(nrnod);
        fr[nrnod] = fr[left] + fr[right];
        lgtext += fr[nrnod];
        arb[nrnod].left = left;
        arb[nrnod].right = right;
    }
///nrnod este radacina arborelui Huffman, pe care il parcurgem si aflam codurile Huffman ale caracterelor
    rsd(nrnod, 0, 0);
}
void afisare()
{
    out << lgtext << '\n';
    for(int i = 1; i <= N; i++)
        out << lgcod[i] << ' ' << cod[i] << '\n';
}
int main()
{
    citire_frecv();
    Huffman();
    afisare();
    return 0;
}