Cod sursa(job #520345)

Utilizator juniorOvidiu Rosca junior Data 8 ianuarie 2011 04:57:35
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.47 kb
// Huffman cu heap, O(n log n)

#include <stdio.h>
#include <algorithm>
#include <vector>

using namespace std;

#define maxn 1000100
#define inf 1LL * 1000000000 * 1000000000
#define mp make_pair
#define ff first
#define ss second
#define pb push_back

struct nod
{
  long long v;
  long f[2];
} nod[2*maxn];

long n, i, j, k, p, a[maxn];
long long b[maxn], m, sol;
long lg[maxn];
vector<pair<long long, long> > v;
pair<long long, long> per;

void df(long poz, long long cod, long nivel)
{
  if(nod[poz].f[0])
  {
    df(nod[poz].f[0], cod * 2, nivel + 1);
    df(nod[poz].f[1], cod * 2 + 1, nivel + 1);
    return;
  }
  lg[poz] = nivel;
  b[poz] = cod;
  sol += lg[poz] * nod[poz].v;
}

void solve()
{
  k = n;
  make_heap(v.begin(), v.end());
  while(v.size() > 1)
  {
    ++k;
    p = 0;
    m = inf;
    for(i = 0; i < 2; i++)
    {
      per = (*v.begin());
      pop_heap(v.begin(), v.end());
      v.pop_back();
      nod[k].f[i] = per.ss;
      nod[k].v += (-per.ff);
    }
    v.pb(mp(-nod[k].v, k));
    push_heap(v.begin(), v.end());
    // sol+=nod[k].v;
  }
  df(k, 0, 0);
}

int main()
{
  freopen("huffman.in", "r", stdin);
  freopen("huffman.out", "w", stdout);
  scanf("%d", &n);
  for(i = 1; i <= n; i++)
  {
    scanf("%d", &nod[i].v);
    v.pb(mp(-(1LL * nod[i].v), i));
  }
  solve();
  printf("%lld\n", sol);
  for(i = 1; i <= n; i++)
  {
    printf("%d %lld\n", lg[i], b[i]);
  }
  return 0;
}