Cod sursa(job #1556493)

Utilizator ThomasFMI Suditu Thomas Thomas Data 24 decembrie 2015 23:22:33
Problema Coduri Huffman Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.97 kb
#include <fstream>
#include <iostream>
#include <queue>
using namespace std;

#define NMax 1000005

struct arbore
{
    long long val;
    arbore *left, *right;
    int dest;

    arbore(long long x, int d)
    {
        val = x;
        left = right = NULL;
        dest = d;
    }

    arbore() {}
};

queue<arbore*> cd1, cd2;

arbore* extract_min()
{
    if(cd1.empty())
    {
        arbore *y = cd2.front();
        cd2.pop();
        return y;
    }
    if(cd2.empty())
    {
        arbore *x = cd1.front();
        cd1.pop();
        return x;
    }

    arbore *x = cd1.front(), *y = cd2.front();
    if(x->val < y->val)
    {
        cd1.pop();
        return x;
    }
    else
    {
        cd2.pop();
        return y;
    }
}

int n;
long long sum;
pair<int,long long> sol[NMax];

void DFS(arbore* nod, long long mask, int depth)
{
    if(nod->left == NULL && nod->right == NULL)
    {
        sol[nod->dest] = make_pair(depth, mask);
    }
    else
    {
        sum += nod->val;
        DFS(nod->left, (mask<<1), depth+1);
        DFS(nod->right, (mask<<1)|1, depth+1);
    }
}

inline void read(int &a)
{
    char c;
    for(c=getchar_unlocked();!isdigit(c);c=getchar_unlocked());
    for(a=0;isdigit(c);c=getchar_unlocked())
        a=(a<<3)+(a<<1)+c-'0';
}

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

    int i,x;
    read(n);
    for(i=1;i<=n;++i)
    {
        read(x);
        cd1.push(new arbore(x, i));
    }

    arbore* aux;
    while(cd1.size() + cd2.size() > 1)
    {
        aux = new arbore();
        aux->left = extract_min();
        aux->right = extract_min();
        aux->val = aux->left->val + aux->right->val;
        cd2.push(aux);
    }

    arbore *root = cd2.front();

    DFS(root, 0, 0);

    cout<<sum<<"\n";

    for(i=1;i<=n;++i)
    {
        cout<<sol[i].first<<" "<<sol[i].second<<"\n";
    }

    return 0;
}