Cod sursa(job #994622)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 5 septembrie 2013 22:32:25
Problema Coduri Huffman Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.38 kb
#include <iostream>
#include <fstream>
#include <cstring>

using namespace std;

const int Nmax = 1000005;

struct nod
{
    long long v;
    int sons[2];

} Arb[2 * Nmax];

int Q1[Nmax], Q2[Nmax];

long long b[Nmax];
int lg[Nmax];

int N;
int inc1 = 1, inc2 = 1, sfc1, sfc2;
long long lungime;

void read()
{
    ifstream f("huffman.in");

    f >> N;

    string file( ( istreambuf_iterator <char>( f ) ), istreambuf_iterator<char>( ) );

    long long l = file.length();
    long long nr = 0;
    int index = 1;

    for ( long long i = 1; i < l; ++i )
            if ( isdigit( file[i] ) )
                    nr = nr * 10 + ( file[i] - 48 );
            else
            {
                Arb[ index++ ].v = nr;
                Q1[ ++sfc1 ] = index - 1;
                nr = 0;
            }

    f.close();
}

inline int indice()
{
    if ( inc1 <= sfc1 && inc2 <= sfc2 )
    {
        if ( Arb[ Q1[inc1] ].v < Arb[ Q2[inc2] ].v )
        {
            int val = Q1[inc1];
            inc1++;
            return val;
        }
        else
        {
            int val = Q2[inc2];
            inc2++;
            return val;
        }
    }

    if ( inc2 <= sfc2 )
    {
        int val = Q2[inc2];
        inc2++;
        return val;
    }

    if ( inc1 <= sfc1 )
    {
        int val = Q1[inc1];
        inc1++;
        return val;
    }

    return 0;
}

void solve()
{
    int n = N;

    for ( int i = 1; i < N; ++i )
    {
        int ind1, ind2;

        ind1 = indice();
        ind2 = indice();

        n++;
        Arb[n].v = Arb[ind1].v + Arb[ind2].v;
        Arb[n].sons[0] = ind1;
        Arb[n].sons[1] = ind2;

        Q2[ ++sfc2 ] = n;
    }
}

void DFS( int root, long long code, int nivel )
{
    if ( Arb[root].sons[0] )
    {
        DFS( Arb[root].sons[0], 2 * code,     nivel + 1 );
        DFS( Arb[root].sons[1], 2 * code + 1, nivel + 1 );
    }
    else
    {
        lg[root] = nivel;
        b[root] = code;
        lungime += lg[root] * Arb[root].v;
    }
}

void print()
{
    freopen("huffman.out", "w", stdout);

    printf("%d\n", lungime);

    for ( int i = 1; i <= N; ++i )
    {
        printf("%d %lld\n", lg[i], b[i]);
    }

    fclose( stdin );
}

int main()
{
    read();
    solve();
    DFS( 2 * N - 1, 0, 0 );
    print();

    return 0;
}