Cod sursa(job #2792314)

Utilizator Stefan_DomuncoStefan Domunco Stefan_Domunco Data 1 noiembrie 2021 14:04:07
Problema Coduri Huffman Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.93 kb
#include <bits/stdc++.h>
#define N NULL
using namespace std;

ifstream fin("huffman.in");
ofstream fout("huffman.out");
const int NMAX = 1e6+6;

struct nod
{
    nod *left, *right;
    int ad, poz;
    long long val, dec;
    nod(long long _val=-1, nod* _left = N, nod* _right = N, int _poz = -1)
    {
        val = _val;
        left = _left;
        right = _right;
        poz = _poz;
    }


}w[NMAX], x[NMAX];///w noduri principale si intermediare
nod *root;
int n;
long long sum;

///pun 0 pe stanga si 1 pe dreapta
void dfs(nod* nod, int ad, long long val)
{
    if(nod -> left != N)
        dfs(nod -> left, ad+1, val << 1);
    if(nod -> left != N)
        dfs(nod -> right, ad+1, (val+1) << 1);
    if(nod -> poz > 0)
        w[nod -> poz].ad = ad, w[nod -> poz].dec = val;
    else sum += nod->val;
}

void huffman()
{
    w[n+1].val = LONG_LONG_MAX;
    ///x - valoarea noduri intermediare
    //nod x[NMAX];
    int stop, i = 1, j;
    stop = 0;
    j = 1;

    ///cat timp am cel putin 2 elemente in una dintre cele doua cozi
    while(i < n || j < stop)
    {
        nod *first, *second;
        if(j <= stop && x[j].val < w[i].val)
            first = &x[j], ++j;
        else first = &w[i], ++i;

        if(j <= stop && x[j].val < w[i].val)
            second = &x[j], ++j;
        else second = &w[i], ++i;

        x[++stop] = nod(first->val+second->val, first, second);
    }

    ///cazul in care am un singur element si nu formez a doua coada
    if(i == n)
        root = &w[n];
    else root = &x[stop];///ultimul nod ramas, adica radacina

    dfs(root, 0ll, 0ll);
}
int main()
{
    int i;
    long long val;
    fin >> n;
    for(i = 1; i <= n; ++i)
    {
        fin >> val;
        w[i] = nod(val, N, N, i);
    }

    huffman();
    fout << sum << '\n';
    for(i = 1; i <= n; ++i)
        fout << w[i].ad << ' ' << w[i].dec << '\n';

    return 0;
}