Cod sursa(job #1168666)

Utilizator mirceadinoMircea Popoveniuc mirceadino Data 9 aprilie 2014 11:10:44
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.73 kb
#include<cstdio>
#include<deque>

using namespace std;

typedef long long int lld;
typedef pair<lld,int> PII;
const int NMAX = 1000000+5;
const lld LINF = (1LL<<62);

void Read(),Solve(),Print();

int N,M;
int V[NMAX];
int Lenght[NMAX];
lld Code[NMAX];
lld LgMin;
deque<PII> A,B;
PII Sons[NMAX];

void Get_Value(PII &X)
{
    lld a,b;

    if(!A.empty()) a = A.front().first;
    else a = LINF;

    if(!B.empty()) b = B.front().first;
    else b = LINF;

    if(a < b)
    {
        X = A.front();
        A.pop_front();
    }
    else
    {
        X = B.front();
        B.pop_front();
    }
}

void DFS(int node,int lenght,lld code)
{
    if(node <= N)
    {
        Lenght[node] = lenght;
        Code[node] = code;
        return;
    }
    DFS(Sons[node].first, lenght+1, 2*code);
    DFS(Sons[node].second, lenght+1, 2*code+1);
}

int main()
{
    Read();
    Solve();
    Print();

    return 0;
}

void Read()
{
    int i;

    freopen("huffman.in","r",stdin);
    freopen("huffman.out","w",stdout);

    scanf("%d",&N);

    for(i = 1; i <= N; i++)
        scanf("%d",&V[i]);
}

void Solve()
{
    int i;
    PII Left,Right;

    for(i = 1; i <= N; i++)
        A.push_back(make_pair(V[i],i));

    M = N;

    for(i = 1; i < N; i++)
    {
        Get_Value(Left);
        Get_Value(Right);
        M++;
        Sons[M] = make_pair(Left.second, Right.second);
        B.push_back(make_pair(Left.first + Right.first, M));
    }

    DFS(M,0,0LL);

    for(i = 1; i <= N; i++)
        LgMin += V[i] * Lenght[i];
}

void Print()
{
    int i;

    printf("%lld\n",LgMin);

    for(i = 1; i <= N; i++)
        printf("%d %lld\n",Lenght[i],Code[i]);
}