Cod sursa(job #750439)

Utilizator PetcuIoanPetcu Ioan Vlad PetcuIoan Data 22 mai 2012 09:19:36
Problema Coduri Huffman Scor 65
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
#include<stdio.h>
#include<assert.h>

#include<algorithm>
#include<vector>
#include<functional>
#include<queue>

using namespace std;

const int kmaxc = 1000005;
vector<int> graph[2 * kmaxc];
int no_char, last, freq[kmaxc], code[kmaxc], len[kmaxc], vis[2 * kmaxc];

void read(){
  assert(freopen("huffman.in", "r", stdin));

  scanf("%d", &no_char);

  for(int i = 1 ;i <= no_char; ++i)
      scanf("%d", &freq[i]);
}

int c_code = 0, c_len = 0;

void get_graph(){
  priority_queue< pair<long long, int>, vector< pair<long long, int> >, greater< pair<long long, int> > > h;

  for(int i = 1; i <= no_char; ++i)
    h.push(make_pair(freq[i], i));

  last = no_char;
  pair<long long, int> one, two;
  while(h.size() > 1){
    one = h.top();
    h.pop();

    two = h.top();
    h.pop();

    ++last;
    graph[last].push_back(one.second);
    graph[last].push_back(two.second);

    h.push(make_pair(one.first + two.first, last));
  }

}

void dfs(int x){
  vis[x] = 1;

  if(graph[x].size()){
    ++c_len;
    c_code = c_code * 2;

    dfs(graph[x][0]);

    ++c_len;
    c_code = c_code * 2;
    ++c_code;

    dfs(graph[x][1]);
  }
  else{
    len[x] = c_len;
    code[x] = c_code;
  }

  --c_len;
  c_code /= 2;
}

void solve(){
    get_graph();

    dfs(last);
}

void write(){
  assert(freopen("huffman.out", "w", stdout));

  long long sol = 0;
  for(int i = 1; i <= no_char; ++i)
    sol = sol + freq[i] * len[i];

  printf("%lld\n", sol);

  for(int i = 1; i <= no_char; ++i)
    printf("%d %d\n", len[i], code[i]);

}

int main(){
  read();
  solve();
  write();
  return 0;
}