Cod sursa(job #2725609)

Utilizator Alex_tz307Lorintz Alexandru Alex_tz307 Data 19 martie 2021 12:34:06
Problema Coduri Huffman Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.75 kb
#include <bits/stdc++.h>

using namespace std;
using int64 = long long;

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

struct node {
  node *st, *dr;
  int ind;
};

const int NMAX = 1e6 + 6;
int N, lg[NMAX], idx;
int64 sol[NMAX], wt[NMAX << 1], ans;
queue<node*> Q1, Q2;

void read_input() {
  fin >> N;
  for (int i = 1; i <= N; ++i) {
    fin >> wt[i];
    node *p = new node;
    p->ind = i;
    p->st = p->dr = nullptr;
    Q1.emplace(p);
  }
}

node* take_best() {
  node *ans;
  if (Q2.empty()) {
    ans = Q1.front();
    Q1.pop();
  } else {
    if (Q1.empty()) {
      ans = Q2.front();
      Q2.pop();
    } else {
      int64 wt1 = wt[Q1.front()->ind], wt2 = wt[Q2.front()->ind];
      if (wt1 < wt2) {
        ans = Q1.front();
        Q1.pop();
      } else {
        ans = Q2.front();
        Q2.pop();
      }
    }
  }
  return ans;
}

void dfs(node *u, int64 mask, int depth) {
  if (u->ind <= N) {
    sol[u->ind] = mask;
    lg[u->ind] = depth;
    ans += wt[u->ind] * depth;
    return;
  }
  if (u->st)
    dfs(u->st, mask << 1LL, depth + 1);
  if (u->dr)
    dfs(u->dr, mask << 1LL | 1LL, depth + 1);
}

void solve() {
  idx = N;
  while (Q1.size() + Q2.size() > 1) {
    node *lSon = take_best(), *rSon = take_best();
    node *parent = new node;
    wt[++idx] = wt[lSon->ind] + wt[rSon->ind];
    parent->ind = idx;
    parent->st = lSon;
    parent->dr = rSon;
    Q2.emplace(parent);
  }
  node *root = Q2.front();
  dfs(root, 0, 0);
  fout << ans << '\n';
  for (int i = 1; i <= N; ++i)
    fout << lg[i] << ' ' << sol[i] << '\n';
}

void close_files() {
  fin.close();
  fout.close();
}

int main() {
  read_input();
  solve();
  close_files();
  return 0;
}