Cod sursa(job #525352)

Utilizator vladiiIonescu Vlad vladii Data 24 ianuarie 2011 21:13:59
Problema Coduri Huffman Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.14 kb
//Huffman e un algoritm ce minimizeaza suma(val[i] * h[i])
//unde h[] = adincimea in arbore, val[] = valoarea nodului
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
#define maxn 1000010
#define LL long long

int N, nrnod, sol;
LL B[2*maxn], lg[2*maxn];

struct vector {
    int st, dr;
    LL val;
} A[2 * maxn];

queue<int> Q1, Q2;

void solve() {
    int i, x[3], ok = 1;

    while(ok) {
         //aleg cele mai mici 2 elemente
         for(i=1; i<=2; i++) {
              if(Q1.size() && Q2.size()) {
                   if(A[ Q1.front() ].val < A[ Q2.front() ].val) {
                        x[i] = Q1.front(); Q1.pop();
                   }
                   else {
                        x[i] = Q2.front(); Q2.pop();
                   }
              }
              else if(Q1.size() && !Q2.size()) {
                   x[i] = Q1.front(); Q1.pop();
              }
              else if(!Q1.size() && Q2.size()) {
                   x[i] = Q2.front(); Q2.pop();
              }
         }

         nrnod ++;
         A[nrnod].val = A[ x[1] ].val + A[ x[2] ].val;
         A[nrnod].st = x[1], A[nrnod].dr = x[2];

         if(!Q1.size()) {
              Q1.push(nrnod);
         }
         else {
              Q2.push(nrnod);
         }

         if(Q1.size() == 0 && Q2.size() == 1) { ok = 0; }
         if(Q1.size() == 1 && Q2.size() == 0) { ok = 0; }
    }
}

void DFS(int nod, int lvl, LL cod) {
    if(A[nod].st || A[nod].dr) {
         sol += A[nod].val;
    }

    lg[nod] = lvl; B[nod] = cod;

    if(A[nod].st) {
         DFS(A[nod].st, lvl + 1, 2 * cod); //pun 0 pe muchie
    }
    if(A[nod].dr) {
         DFS(A[nod].dr, lvl + 1, 2 * cod + 1); //pun 1 pe muchie
    }
}

int main() {
    FILE *f1=fopen("huffman.in", "r"), *f2=fopen("huffman.out", "w");
    int i, j, p;

    fscanf(f1, "%d\n", &N);
    for(i=1; i<=N; i++) {
         fscanf(f1, "%d\n", &A[i].val);

         A[i].st = A[i].dr = 0;

         Q1.push(i);
    }

    nrnod = N;

    solve();
    DFS(nrnod, 0, 0);

    fprintf(f2, "%lld\n", sol);
    for(i=1; i<=N; i++) {
         fprintf(f2, "%lld %lld\n", lg[i], B[i]);
    }

    fclose(f1); fclose(f2);
    return 0;
}