Pagini recente » Cod sursa (job #2286685) | Cod sursa (job #2886990) | Cod sursa (job #657538) | Cod sursa (job #2353261) | Cod sursa (job #1468313)
#include <stdio.h>
#include <queue>
#include <algorithm>
#define MAX 1000005
using namespace std;
typedef struct{
long long v;
int l, r, p;
} node;
typedef struct{
int l, p;
long long r;
} node2;
queue<node> qni, qne;
node arb[2 * MAX];
node2 v[MAX];
int n, i, x, poz, p;
long long lg;
int compar(const void* a, const void* b){
return ((node*)a)->p - ((node*)b)->p;
}
node createnode(node a, node b, int poz);
void huffman();
void dfs(node n, long long code, int level);
int main(){
freopen("huffman.in", "r", stdin);
freopen("huffman.out", "w", stdout);
scanf("%d", &n);
for(i = 0; i < n; i++){
scanf("%d", &x);
arb[i].v = x;
arb[i].l = arb[i].r = -1;
arb[i].p = i;
qne.push(arb[i]);
}
poz = n;
huffman();
printf("%lld\n", lg);
dfs(arb[poz - 1], 0, 0);
qsort(v, n, sizeof(node2), compar);
for(i = 0; i < n; i++)
printf("%d %lld\n", v[i].l, v[i].r);
return 0;
}
node createnode(node a, node b, int poz){
node x;
x.v = a.v + b.v;
x.l = a.p;
x.r = b.p;
x.p = poz;
return x;
}
void huffman(){
while(1){
node a, b;
if(qni.empty()){
a = qne.front(); qne.pop();
b = qne.front(); qne.pop();
arb[poz] = createnode(a, b, poz); qni.push(arb[poz]);
lg += arb[poz++].v;
}
else{
if(qne.empty()){
a = qni.front(); qni.pop();
if(qni.empty())
return;
else{
b = qni.front(); qni.pop();
arb[poz] = createnode(a, b, poz); qni.push(arb[poz]);
lg += arb[poz++].v;
}
}
else{
if(qne.front().v < qni.front().v){
a = qne.front(); qne.pop();
}
else{
a = qni.front(); qni.pop();
}
if(qne.empty()){
b = qni.front(); qni.pop();
}
else if(qni.empty()){
b = qne.front(); qne.pop();
}
else{
if(qne.front().v < qni.front().v){
b = qne.front(); qne.pop();
}
else{
b = qni.front(); qni.pop();
}
}
arb[poz] = createnode(a, b, poz); qni.push(arb[poz]);
lg += arb[poz++].v;
}
}
}
}
void dfs(node n, long long code, int level){
if(n.l == -1){
v[p].l = level;
v[p].r = code;
v[p++].p = n.p;
return;
}
dfs(arb[n.l], 2 * code, level + 1);
dfs(arb[n.r], 2 * code + 1, level + 1);
}