Cod sursa(job #1834706)

Utilizator TincaMateiTinca Matei TincaMatei Data 24 decembrie 2016 22:40:51
Problema Coduri Huffman Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 1.51 kb
#include <cstdio>

typedef long long i64;

const int MAX_N = 1000000;
const int MAX_NOD = 2 * MAX_N - 1;
i64 fv[1+MAX_NOD];
int fii[2][1+MAX_NOD];
int st1, st2;
int cod[1+MAX_NOD], depth[1+MAX_NOD];

void bfs(int node, int code, int dep) {
  if(node != 0) {
    cod[node] = code;
    depth[node] = dep;
    bfs(fii[0][node], code * 2, dep + 1);
    bfs(fii[1][node], code * 2 + 1, dep + 1);
  }
}

int main() {
  int n, unused, n1, n2;
  i64 lg, min;
  FILE *fin = fopen("huffman.in", "r");
  fscanf(fin, "%d", &n);
  for(int i = 1; i <= n; ++i)
    fscanf(fin, "%lld", &fv[i]);
  fclose(fin);

  unused = n + 1;
  lg = 0LL;
  st1 = 1;
  st2 = n + 1;
  for(int i = 0; i < n - 1; ++i) {
    min = 1000000000000000001LL;
    n1 = n2 = 0;
    if(st1 + 1 <= n && fv[st1] + fv[st1 + 1] < min) {
      min = fv[st1] + fv[st1 + 1];
      n1 = st1;
      n2 = st1 + 1;
    }
    if(st1 <= n && st2 < unused && fv[st1] + fv[st2] < min) {
      min = fv[st1] + fv[st2];
      n1 = st1;
      n2 = st2;
    }
    if(st2 + 1 < unused && fv[st2] + fv[st2 + 1] < min) {
      min = fv[st2] + fv[st2 + 1];
      n1 = st2;
      n2 = st2 + 1;
    }
    fv[unused] = min;
    lg = lg + min;
    fii[0][unused] = n1;
    fii[1][unused] = n2;
    unused++;
    if(n1 <= n)
      ++st1;
    else
      ++st2;
    if(n2 <= n)
      ++st1;
    else
      ++st2;
  }
  bfs(unused - 1, 0, 0);

  FILE *fout = fopen("huffman.out", "w");
  fprintf(fout, "%lld\n", lg);
  for(int i = 1; i <= n; ++i)
    fprintf(fout, "%d %d\n", depth[i], cod[i]);
  fclose(fout);
  return 0;
}