Cod sursa(job #870820)

Utilizator visanrVisan Radu visanr Data 3 februarie 2013 23:00:45
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.88 kb
#include <fstream>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;

#define Nmax 1000010
#define LL long long

ifstream in("huffman.in");
char S[1 << 18];
int NowPos;

int Son[2 * Nmax][2], Length[Nmax], N;
int Q[2][Nmax], Start[2], End[2];
LL V[2 * Nmax], ValBin[Nmax], Ans;

void Check()
{
    if(S[NowPos] == 0)
    {
        in.get(S, 1 << 18, '\0');
        NowPos = 0;
    }
}

int Get()
{
    int Nr = 0;
    while(!isdigit(S[NowPos]))
        NowPos ++, Check();
    while(isdigit(S[NowPos]))
        Nr = Nr * 10 + S[NowPos] - '0', NowPos ++, Check();
    return Nr;
}

void DFS(int Node, int CrtLg, LL CrtBin)
{
    if(Son[Node][0])
    {
        DFS(Son[Node][0], CrtLg + 1, CrtBin * 2);
        DFS(Son[Node][1], CrtLg + 1, CrtBin * 2 + 1);
        return ;
    }
    Length[Node] = CrtLg;
    ValBin[Node] = CrtBin;
}

int main()
{
    ofstream cout("huffman.out");
    int i, j;
    Check();
    N = Get();
    Start[0] = Start[1] = 1;
    End[0] = End[1] = 0;
    for(i = 1; i <= N; i++)
    {
        V[i] = Get();
        Q[0][++End[0]] = i;
    }
    int CrtNode = N;
    while(Start[0] + Start[1] <= End[0] + End[1])
    {
        CrtNode ++;
        for(i = 0; i < 2; i++)
        {
            int Pos = -1, QIdx;
            for(j = 0; j < 2; j++)
                if(Start[j] <= End[j] && (Pos == -1 || V[Pos] > V[Q[j][Start[j]]]))
                {
                    Pos = Q[j][Start[j]];
                    QIdx = j;
                }
            Start[QIdx] ++;
            V[CrtNode] += V[Pos];
            Son[CrtNode][i] = Pos;
        }
        Q[1][++End[1]] = CrtNode;
    }
    DFS(CrtNode, 0, 0);
    for(i = 1; i <= N; i++) Ans += 1LL * Length[i] * V[i];
    cout << Ans << "\n";
    for(i = 1; i <= N; i++) cout << Length[i] << " " << ValBin[i] << "\n";
    return 0;
}