Pagini recente » Cod sursa (job #1441918) | Cod sursa (job #3147359)
#include <stdio.h>
#include <queue>
#define magic_sauce inline __attribute__((always_inline))
using ll = long long;
const int MAXN = 1e6;
const int INF = 1e9;
const int NIL = -1;
struct Node {
ll freq;
int left;
ll right;
} nodes[2 * MAXN];
int nnodes;
std::queue<int> p, q; // initial and auxilary queue
// gets and reomves node with minimum frequency
magic_sauce int minf(){
int ret;
if( !p.size() ){
ret = q.front();
q.pop();
}else if( !q.size() ){
ret = p.front();
p.pop();
}else if( nodes[p.front()].freq < nodes[q.front()].freq ){
ret = p.front();
p.pop();
}else{
ret = q.front();
q.pop();
}
return ret;
}
void label( int root, int len, ll code ){
if( nodes[root].left == NIL ){
nodes[root].left = len; // refolosim memoria useless
nodes[root].right = code;
return;
}
label( nodes[root].left, len + 1, code * 2 );
label( nodes[root].right, len + 1, code * 2 + 1 );
}
int main(){
FILE *fin = fopen( "huffman.in", "r" );
FILE *fout = fopen( "huffman.out", "w" );
int n, i, a, b;
ll len;
fscanf( fin, "%d", &n );
for( i = 0 ; i < n ; i++ ){
nodes[i].left = nodes[i].right = NIL;
fscanf( fin, "%lld", &nodes[i].freq );
p.push( i );
}
len = 0;
nnodes = n;
while( p.size() + q.size() > 1 ){
a = minf();
b = minf();
len += nodes[a].freq + nodes[b].freq;
nodes[nnodes] = Node{ nodes[a].freq + nodes[b].freq, a, b };
q.push( nnodes++ );
}
label( nnodes - 1, 0, 0 );
fprintf( fout, "%lld\n", len );
for( i = 0 ; i < n ; i++ )
fprintf( fout, "%d %lld\n", nodes[i].left, nodes[i].right );
fclose( fin );
fclose( fout );
return 0;
}