Cod sursa(job #491833)

Utilizator iraIrina Stanescu ira Data 12 octombrie 2010 16:10:34
Problema Coduri Huffman Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <algorithm>

using namespace std;

#define infile "huffman.in"
#define outfile "huffman.out"

#define NMAX 1000000


long long lg[NMAX], val[NMAX];

typedef struct node {
    long long freq;
    int index;
    struct node *father, *right, *left;
} node;

node *connect(node *a, node *b) {

    node *result = new node;
    result->freq = a->freq + b->freq;
    result->left = a;
    result->right = b;
    a->father = result;
    b->father = result;

    return result;
}

node *get_min(queue<node*> *fq, queue<node*> *sq) {
    node *min = NULL;
    if (fq->empty()) {
        min = sq->front();
        sq->pop();
    } else if (sq->empty()) {
        min = fq->front();
        fq->pop();
    } else if (fq->front()->freq <= sq->front()->freq) {
        min = fq->front();
        fq->pop();
    } else {
        min = sq->front();
        sq->pop();
    }

    return min;
}


void dfs(node *nd, long long value, long long len) {

    if (nd->left == NULL) {
        lg[nd->index] = len;
        val[nd->index] = value;
        return;
    }
    
    dfs(nd->left, value * 2, len + 1);
    dfs(nd->right, value * 2 + 1, len + 1);
}

FILE *fin, *fout;

int main() {

    fin = freopen(infile, "r", stdin);
    fout = freopen(outfile, "w", stdout);

    int n;
    scanf("%d", &n);

    queue<node*> *fq, *sq;

    fq = new queue<node*>();
    sq = new queue<node*>();

    long long sol = 0;

    for (int i = 0; i < n; i++) {
        node *nd = new node;
        scanf("%lld", &nd->freq);
        nd->index = i;
        nd->father = nd->right = nd->left = NULL;
        fq->push(nd);
    }

    node *root;

    while (true) {
        node *a, *b;
        a = get_min(fq, sq);
        b = get_min(fq, sq);
        sq->push(connect(a,b));

        sol += sq->back()->freq;    
        if (sq->size() == 1 && fq->empty()) {
            root = sq->front();
            break;
        }
    }

    dfs(root, 0, 0);

    printf("%lld\n", sol);
    for (int i = 0; i < n; i++) {
        printf("%lld %lld\n", lg[i], val[i]);
    }


    delete fq;
    delete sq;
    return 0;
}