Cod sursa(job #903485)

Utilizator sebii_cSebastian Claici sebii_c Data 1 martie 2013 21:17:00
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.19 kb
#include <cstdio>
#include <cstring>

#include <iostream>
#include <queue>
#include <set>
#include <vector>

using namespace std;

struct node {
    int index;

    node *left;
    node *right;
    long long val;

    node(int _index, long long _val, node *_left, node *_right): 
        index(_index), val(_val), left(_left), right(_right) {}
};

const int MAXN = 1000005;

int len[MAXN];
long long code[MAXN];

void dfs(node *root, int d, long long val)
{
    if (root->index != -1) {
        len[root->index] = d;
        code[root->index] = val;
        return;
    }

    dfs(root->left, d + 1, val * 2);
    dfs(root->right, d + 1, val * 2 + 1);
}

node *get_min(queue<node*>& nodes, queue<node*>& tree)
{
    node *retval;
    if (nodes.empty()) {
        retval = tree.front();
        tree.pop();
    } else if (tree.empty()) {
        retval = nodes.front();
        nodes.pop();
    } else {
        if (nodes.front()->val < tree.front()->val) {
            retval = nodes.front();
            nodes.pop();
        } else {
            retval = tree.front();
            tree.pop();
        }
    }

    return retval;
}

const int MAXC = 11000000;

char buff[MAXC];

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

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

    queue<node *> nodes;
    queue<node *> tree;

    cin.getline(buff, MAXC, EOF);
    int j = 0;
    int k = strlen(buff);
    for (int i = 0; i < n; ++i) {
        long long v = 0;
        for (; j < k && buff[j] < '0' || buff[j] > '9'; ++j);
        for (; j < k && buff[j] >= '0' && buff[j] <= '9'; ++j)
            v = v * 10 + (buff[j] - '0');

        nodes.push(new node(i, v, NULL, NULL));
    }

    node *root;
    long long total_value = 0;
    while (true) {
        node *low = get_min(nodes, tree);
        if (tree.empty() && nodes.empty()) {
            dfs(low, 0, 0);
            break;
        }

        node *next = get_min(nodes, tree);
        tree.push(new node(-1, low->val + next->val, low, next));

        total_value += low->val;
        total_value += next->val;
    }

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

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

    return 0;
}