Cod sursa(job #3147359)

Utilizator mircea_007Mircea Rebengiuc mircea_007 Data 25 august 2023 23:05:57
Problema Coduri Huffman Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.65 kb
#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;
}