Cod sursa(job #670321)

Utilizator andumMorie Daniel Alexandru andum Data 28 ianuarie 2012 20:40:45
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.85 kb
#include <cstdio>
#include <queue>

using namespace std;

const int nmax = 1000005;

struct nod
{
    nod *left, *right;
    int index, weight;
} *min1, *min2;

long long code[nmax],internal_weight=0;
int depth[nmax];
queue < nod* > Q1,Q2;

inline nod* getMin()
{
    nod *x;
    if (Q2.empty())
    {
        x=Q1.front();
        Q1.pop();
        return x;
    }
    else if (Q1.empty())
    {
        x=Q2.front();
        Q2.pop();
        return x;
    }
    else
    {
        if (Q1.front()->weight<Q2.front()->weight)
        {
            x=Q1.front();
            Q1.pop();
        }
        else
        {
            x=Q2.front();
            Q2.pop();
        }
        return x;
    }
}

inline void df(nod *x, int code_size, long long code_value)
{
    if (x->index)
    {
        depth[x->index]=code_size;
        code[x->index]=code_value;
        internal_weight+=x->weight*code_size;
        return;
    }
    df(x->left, code_size+1, code_value<<1);
    df(x->right, code_size+1, (code_value<<1)+1);
}

int main()
{
    freopen("huffman.in", "r", stdin);
    freopen("huffman.out", "w", stdout);
    int n,w;
    scanf("%d", &n);
    for (int i=1; i<=n; ++i)
    {
        scanf("%d", &w);
        nod *x;
        x = new nod;
        x->index=i;
        x->weight=w;
        x->left=x->right=NULL;
        Q1.push(x);
    }
    int k=0;
    while (k<n-1)
    {
        ++k;
        min1=getMin();
        min2=getMin();
        nod *x;
        x = new nod;
        x->left=min1;
        x->right=min2;
        x->weight=min1->weight+min2->weight;
        x->index=0;
        Q2.push(x);
    }
    nod *root = getMin();
    df(root,0,0);

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

    for (int i=1; i<=n; ++i)
        printf("%d %lld\n", depth[i], code[i]);

    return 0;
}