Cod sursa(job #994515)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 5 septembrie 2013 18:05:11
Problema Coduri Huffman Scor 65
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

const int Nmax = 1000005;

struct node
{
    uint64_t v;
    uint32_t sons[2];

} Arb[2 * Nmax];

struct cmp
{
    bool operator () ( const int &a, const int &b ) const
    {
        return Arb[a].v > Arb[b].v;
    }
};


priority_queue < int, vector <int>, cmp > MinHeap;
uint64_t v[Nmax], b[Nmax], lg[Nmax];

uint32_t N;
uint64_t lungime;

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

    f >> N;

    for ( uint32_t i = 1; i <= N; ++i )
    {
        f >> Arb[i].v;

        MinHeap.push( i );
    }

    f.close();
}

void solve()
{
    uint32_t n = N;

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

        ind1 = MinHeap.top();
        MinHeap.pop();

        ind2 = MinHeap.top();
        MinHeap.pop();

        n++;

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

        MinHeap.push( n );
    }
}

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

void print()
{
    ofstream g("huffman.out");

    g << lungime << "\n";

    for ( int i = 1; i <= N; ++i )
    {
        g << lg[i] << " " << b[i] << "\n";
    }

    g.close();
}

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

    return 0;
}