Cod sursa(job #774178)

Utilizator igsifvevc avb igsi Data 3 august 2012 18:12:05
Problema Coduri Huffman Scor 80
Compilator c Status done
Runda Arhiva educationala Marime 2.65 kb
#include <stdio.h>
#define maxt 2100000
#define maxn 1050000

struct Tree { long long v; int left, right; } T[maxt];

int N, root, Q[maxt], L[maxt];
long long lg, B[maxt];

void read () ;
void buildTree () ;
void BF () ;

int main ()
{
    FILE *out; int i;

    read () ;
    buildTree () ;
    BF () ;

    out = fopen("huffman.out", "w");
    fprintf (out, "%lld\n", lg);
    for(i = 0; i < N; ++i)
        fprintf (out, "%d %lld\n", L[i], B[i]);

    fclose(out);
    return 0;
}

void BF ()
{
    int l, r, n, length;
    long long path;
    l = r = 0;
    Q[0] = root;
    L[root] = 0;
    B[root] = 0;

    while( l <= r )
    {
        n = Q[l]; ++l;
        if (n >= N)
        {
            length = L[n] + 1;
            path = B[n];
            if ( T[n].left != -1 )
            {
                Q[++r] = T[n].left;
                L[ Q[r] ] = length;
                B[ Q[r] ] = path << 1;
            }
            if ( T[n].right != -1)
            {
                Q[++r] = T[n].right;
                L[ Q[r] ] = length;
                B[ Q[r] ] = (path << 1) + 1;
            }
        }
        else
        {
            lg += T[n].v * L[n];
        }
    }
}

void buildTree ()
{
    int l[2], r[2], choose[2], pos[2], i, k;

    k = N -1;
    l[0] = l[1] = 0;
    r[0] = N-1; r[1] = -1;

    while (l[0] <= r[0] || l[1] < r[1])
    {
        i = -1;
        if (l[0] <= r[0])
        {
            pos[0] = l[0];  choose[0] = 0;  ++i;
            if (l[0]+1 <= r[0])
            {
                pos[1] = l[0]+1; choose[1] = 0;  ++i;
            }
        }

        if (l[1] <= r[1])
        {
            if ( i == -1 || T[ pos[0] ].v > T[ Q[ l[1] ] ].v )
            {
                pos[1] = pos[0]; choose[1] = 0;
                pos[0] = Q[ l[1] ]; choose[0] = 1;
                if ( l[1]+1 <= r[1] && (i == -1 || T[ pos[1] ].v > T[ Q[ l[1]+1 ] ].v) )
                {
                    pos[1] = Q[ l[1]+1 ]; choose[1] = 1;
                }
            }
            else if ( i == 0 || T[ pos[1] ].v > T[ Q[ l[1] ] ].v)
            {
                pos[1] = Q[ l[1] ]; choose[1] = 1;
            }
        }

        ++l[ choose[0] ]; ++l[ choose[1] ];
        T[++k].v = T[ pos[0] ].v + T[ pos[1] ].v;
        T[k].left = pos[0];
        T[k].right = pos[1];
        Q[ ++r[1] ] = k;
    }
    root = Q[ l[1] ];
}

void read () {
    int i;  FILE *in = fopen ("huffman.in", "r");
    fscanf (in, "%d", &N);
    for (i = 0; i < N; ++i)
    {
        fscanf (in, "%lld", &T[i].v);
        T[i].left = T[i].right = -1;
    }
    fclose (in);
}