Cod sursa(job #742488)

Utilizator Alexa_ioana_14Antoche Ioana Alexandra Alexa_ioana_14 Data 30 aprilie 2012 15:08:51
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.37 kb
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;

#define U long long
#define NM 2000000

U frecventa[NM],ind[NM],N,nInit,reprezentare[NM],lung = 0;
int dep[NM],leftSon[NM],rightSon[NM];
queue <int> q1,q2;
inline void readInputData()
{
    scanf("%lld",&nInit);
    N = nInit;
    for (U i=1; i<=nInit; ++i)
    {
        scanf("%lld",&frecventa[i]);
        ind[i]=i;
        q1.push(i);
    }
}

inline void update(const int &p1, const int &p2)
{
    ++N;
    frecventa[N] = frecventa[ ind[p1] ] + frecventa[ ind[p2] ];
    leftSon[N] = p1;
    rightSon[N] = p2;
    ind[N]=N;
    if (q1.empty() && q2.empty() )
        return;
    q2.push(N);
}

inline void verific(queue<int> &q, int &poz1,int &poz2)
{
    poz1=q.front();
    q.pop();
    poz2=q.front();
    q.pop();
    update(poz1,poz2);
}

inline void capete ( int &p)
{
    if (frecventa[ind[q1.front()]] < frecventa[ ind[ q2.front()]])
    {
        p = q1.front();
        q1.pop();
        return;
    }
    p = q2.front();
    q2.pop();
}

inline void solveHuffman()
{
    int poz1,poz2;
    while ( !q1.empty () || !q2.empty() )
    {
        if (q1.empty())
        {
            verific(q2,poz1,poz2);
            continue;
        }

        if (q2.empty())
        {
            verific(q1,poz1,poz2);
            continue;
        }

        capete(poz1);

        if (q1.empty())
        {
            poz2 = q2.front();
            q2.pop();
            update(poz1,poz2);
            continue;
        }

        if (q2.empty())
        {
            poz2 = q1.front();
            q1.pop();
            update(poz1,poz2);
            continue;
        }
        capete(poz2);
        update(poz1,poz2);
    }
}

void df(int nod, int cod,int nivel)
{
    if (ind[nod] !=N )
        lung += frecventa[ind[nod]];

    //funza
    if (ind[nod] <= nInit)
    {
        dep[ind[nod]] = nivel;
        reprezentare[ind[nod]] = cod;
        return;
    }

    df(leftSon[ind[nod]],(cod<<1) ,nivel+1);
    df(rightSon[ind[nod]],(cod<<1)+1 ,nivel+1);
}

inline void afis()
{
    printf("%lld\n",lung);
    for (int i=1; i<=nInit; ++i)
        printf("%d %lld\n",dep[i],reprezentare[i]);
}
int main()
{
    freopen ("huffman.in","r",stdin);
    freopen ("huffman.out","w",stdout);
    readInputData();
    solveHuffman();
    df(N,0,0);
    afis();
    /*for (int i=1; i<=N; ++i)
        printf("%u\n",frecventa[i]);*/
    return 0;
}