Cod sursa(job #1292833)

Utilizator Al3ks1002Alex Cociorva Al3ks1002 Data 14 decembrie 2014 20:36:30
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.27 kb
#include<cstdio>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<bitset>
#include<deque>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<unordered_map>

#define ll long long
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>

using namespace std;

const int NMAX = 1000005;
const ll INF = 1LL << 62;

int N, i, St[2 * NMAX], Dr[2 * NMAX], Lung[NMAX], Ninit, F[NMAX], StN, DrN;
ll XA, XB, StV, DrV, Sol[NMAX], Lg;

deque<pli> A, B;

void DFS(int Nod, int L, ll Sum)
{
    if(St[Nod])
    {
        if(St[Nod]) DFS(St[Nod], L + 1, Sum * 2);
        if(Dr[Nod]) DFS(Dr[Nod], L + 1, Sum * 2 + 1);
    }
    else
    {
        Lung[Nod] = L;
        Sol[Nod] = Sum;
    }
}

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

    scanf("%d", &N);

    for(i = 1; i <= N; i++)
    {
        scanf("%d", &F[i]);
        A.pb(mp(F[i], i));
    }

    for(Ninit = N;;)
    {
        if(!A.empty()) XA = A.front().first;
        else XA = INF;

        if(!B.empty()) XB = B.front().first;
        else XB = INF;

        if(XA < XB)
        {
            StV = XA;
            StN = A.front().second;
            A.pop_front();
        }
        else
        {
            StV = XB;
            StN = B.front().second;
            B.pop_front();
        }

        if(!A.empty()) XA = A.front().first;
        else XA = INF;

        if(!B.empty()) XB = B.front().first;
        else XB = INF;

        if(XA < XB)
        {
            DrV = XA;
            DrN = A.front().second;
            A.pop_front();
        }
        else
        {
            DrV = XB;
            DrN = B.front().second;
            B.pop_front();
        }

        N++;
        St[N] = StN;
        Dr[N] = DrN;
        if(A.empty() && B.empty()) break;
        B.pb(mp(StV + DrV, N));
    }

    DFS(N, 0, 0);

    for(i = 1; i <= Ninit; i++)
        Lg += F[i] * Lung[i];

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

    for(i = 1; i <= Ninit; i++)
        printf("%d %lld\n", Lung[i], Sol[i]);
    return 0;
}