Cod sursa(job #3272761)

Utilizator susdomesticussusdomesticus susdomesticus Data 30 ianuarie 2025 20:19:59
Problema Coduri Huffman Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.72 kb
#define MAX_N 1000000

#include <fstream>
#include <memory>
#include <queue>
using namespace std;

using i64 = long long;

ifstream fin("huffman.in");
ofstream fout("huffman.out");

struct node {
  i64 w;
  int depth;
  size_t index;
  i64 code;

  shared_ptr<node> next[2];

  constexpr bool operator>(const node &other) const {
    return this->w > other.w;
  }
};

vector<node> leaves;
priority_queue<node, vector<node>, greater<node>> nodes;

int main() {
  int n;
  fin >> n;
  leaves = vector<node>(n + 1);
  for (int i = 1; i <= n; i++) {
    node new_node;
    fin >> new_node.w;
    new_node.next[0] = nullptr;
    new_node.next[1] = nullptr;
    new_node.index = i;
    nodes.push(new_node);
  }

  shared_ptr<node> root = nullptr;
  while (!nodes.empty()) {
    node first = nodes.top();
    nodes.pop();

    if (nodes.empty()) {
      root = make_shared<node>(first);
      break;
    }

    node second = nodes.top();
    nodes.pop();

    node father = {first.w + second.w,       0, 0, 0, make_shared<node>(first),
                   make_shared<node>(second)};
    root = make_shared<node>(father);
    nodes.push(father);
  }

  queue<node> q;
  q.push(*root);
  i64 sum = 0;
  while (!q.empty()) {
    node crt = q.front();
    q.pop();

    if (crt.next[0]) {
      crt.next[0]->depth = crt.depth + 1;
      crt.next[0]->code = crt.code * 2;
      q.push(*crt.next[0]);
      crt.next[1]->depth = crt.depth + 1;
      crt.next[1]->code = crt.code * 2 + 1;
      q.push(*crt.next[1]);
    } else {
      sum += crt.depth * crt.w;
      leaves[crt.index] = crt;
    }
  }

  fout << sum << '\n';
  for (size_t i = 1; i < leaves.size(); i++) {
    const auto &node = leaves[i];
    fout << node.depth << ' ' << node.code << '\n';
  }
  return 0;
}