Cod sursa(job #1134145)

Utilizator Mihai22eMihai Ionut Enache Mihai22e Data 6 martie 2014 03:54:13
Problema Coduri Huffman Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.78 kb
#include <queue>

#include <cstdio>
using namespace std;

const int MAX_N = 1000002;
const int SIGMA = 2;

struct Node {
    int ind;
    int sons[SIGMA];
    long long val;
};

int N;
int frequency[MAX_N];
queue < int > a, b;
long long ans;
pair < int, long long > sol[MAX_N];
Node v[2 * MAX_N];

void DFS(Node node, long long code, int lv) {
    if(node.sons[0]) {
        DFS(v[node.sons[0]], code * 2, lv + 1);
        DFS(v[node.sons[1]], code * 2 + 1, lv + 1);
    }
    else {
        sol[node.ind] = make_pair(lv, code);
        ans += (long long) lv * frequency[node.ind];
    }
}

inline int getMin() {
    int ret = 0;

    if(a.empty()) {
        ret = b.front();
        b.pop();
    }
    else if(b.empty()) {
        ret = a.front();
        a.pop();
    }
    else if(v[a.front()].val < v[b.front()].val) {
        ret = a.front();
        a.pop();
    }
    else {
        ret = b.front();
        b.pop();
    }

    return ret;
}

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

    scanf("%d", &N);
    Node temp;
    temp.sons[0] = temp.sons[1] = 0;
    for(int i = 1; i <= N; ++i) {
        scanf("%d", &frequency[i]);

        temp.val = frequency[i];
        temp.ind = i;
        v[i] = temp;
        a.push(i);
    }

    int p = N + 1;
    Node node, temp1, temp2;
    while(!a.empty() || b.size() > 1) {
        temp1 = v[getMin()];
        temp2 = v[getMin()];

        node.val = temp1.val + temp2.val;
        node.ind = p;
        node.sons[0] = temp1.ind, node.sons[1] = temp2.ind;
        v[p] = node;
        ++p;

        b.push(node.ind);
    }

    DFS(node, 0, 0);

    printf("%lld\n", ans);
    for(int i = 1; i <= N; ++i)
        printf("%d %lld\n", sol[i].first, sol[i].second);

    fclose(stdin);
    fclose(stdout);

    return 0;
}