Cod sursa(job #2495716)

Utilizator maria15Maria Dinca maria15 Data 19 noiembrie 2019 19:35:13
Problema Coduri Huffman Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.97 kb
#include <cstdio>
#include <fstream>
#include <cstring>

using namespace std;

FILE *fin = fopen("huffman.in", "r");
FILE *fout = fopen("huffman.out", "w");

long long n, m, i, j, v[1000001], c[2000001], nr[2000001], w[1000001], nrW, SOL;
pair<long long, long long> H[2000001];

void dfs(int nod, int cod, int niv){
    c[nod] = cod;
    nr[nod] = niv;
    if(H[nod].first != 0){
        for(int i = 0;i<2;i++){
           if(i == 0){
                int vecin = H[nod].first;
                dfs(vecin, (cod<<1), niv+1);
                if(H[vecin].first == 0)
                    SOL += nr[vecin]*v[vecin];
           }
           else{
                int vecin = H[nod].second;
                dfs(vecin, (cod<<1) + 1, niv+1);
                if(H[vecin].first == 0)
                    SOL += nr[vecin]*v[vecin];
           }
        }
    }
}

int main(){
    fscanf(fin, "%lld", &n);
    for(i=1;i<=n;i++){
        fscanf(fin, "%lld", &v[i]);
        w[i] = 100000001;
    }
    i = j = 1;
    m = n;
    while(m < 2*n){
        if(v[i] <= w[j] && i <= n && i+1 <=n && v[i+1] <= w[j]){
       /// le iau pe primele doua primul sir
            w[++nrW] = v[i]+v[i+1];
            H[++m] = {i, i+1};
            i += 2;
        }
        else
            if((v[i] <= w[j] && i <= n && ( (i+1 <= n && v[i+1] > w[j]) || (i+1 > n) ))||(i <= n && v[i] > w[j] && ((j+1 < 2*n && w[j+1] > v[i])||(j+1 >= 2*n)))){       /// iau capetele celor doua siruri
                w[++nrW] = v[i] + w[j];
                H[++m] = {i, j+n};
                i++, j++;
            }
            else
                if(j+1 <= 2*n-1 && (i > n || (w[j] < v[i] && w[j+1] < v[i]))){
                    w[++nrW] = w[j] + w[j+1];
                    H[++m] = {j+n, j+n+1};
                    j += 2;
                }

    }
    dfs(2*n-1, 0, 0);
    fprintf(fout,"%lld\n", SOL);
    for(i=1;i<=n;i++)
        fprintf(fout,"%d %lld\n", nr[i], c[i]);
    return 0;
}