Cod sursa(job #2077615)

Utilizator AlexGAlexandru Gheorghe AlexG Data 28 noiembrie 2017 12:34:34
Problema Coduri Huffman Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.66 kb
#include <stdio.h>

const int nMax = 1000000;
struct Nod
{
    long long v;
    int f[2];
} nod[2*nMax - 1];

struct Coada
{
    int i[nMax];
    int s;
    int d;
} c[2];

int n;
int lCod[nMax];
long long cod[nMax], lg;

void parcurgereInAdancime(int i, long long codZ, long n)
{
    if(nod[i].f[0] != -1)
    {
        parcurgereInAdancime(nod[i].f[0], codZ*2, n+1);
        parcurgereInAdancime(nod[i].f[1], codZ*2+1, n+1);
        return;
    }
    lCod[i]=n;
    cod[i]=codZ;
}

int celMaiMicNod()
{
    if(c[0].s > c[0].d)
        return c[1].i[c[1].s++];
    else if(c[1].s > c[1].d)
        return c[0].i[c[0].s++];
    else if(nod[c[0].i[c[0].s]].v < nod[c[1].i[c[1].s]].v)
        return c[0].i[c[0].s++];
    else
        return c[1].i[c[1].s++];
}

void construiesteCoadaNodurilorInterne()
{
    while(c[0].s+c[1].s <= c[0].d+c[1].d)
    {
        Nod p;
        p.f[0] = celMaiMicNod();
        p.f[1] = celMaiMicNod();
        p.v = nod[p.f[0]].v + nod[p.f[1]].v;
        lg += p.v;
        nod[n] = p;
        c[1].i[++c[1].d] = n++;
    }
}

int main()
{
    freopen("huffman.in", "r", stdin);
    freopen("huffman.out", "w", stdout);
    scanf("%d", &n);
    int k = n;
    c[0].s = 0;
    c[0].d = -1;
    for(int i=0; i<n; i++)
    {
        scanf("%I64d", &nod[i].v);
        nod[i].f[0] = -1;
        nod[i].f[1] = -1;
        c[0].i[++c[0].d] = i;
    }
    c[1].s = 0;
    c[1].d = -1;
    construiesteCoadaNodurilorInterne();
    parcurgereInAdancime(c[1].i[c[1].s++], 0, 0);
    printf("%I64d\n", lg);
    for(int i=0; i<k; i++)
        printf("%d %I64d\n", lCod[i], cod[i]);
    return 0;
}