Cod sursa(job #2483200)

Utilizator Ruxandra985Nanu Ruxandra Laura Ruxandra985 Data 29 octombrie 2019 15:01:26
Problema Coduri Huffman Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.74 kb
#include <cstdio>
#define DIMN 1000010
#define INF 1000000000000000000
using namespace std;
long long sol = 0;
int nodes,root , n;
long long fq[DIMN] , code[2*DIMN];
int leaf[DIMN] , intern[DIMN] , left[2*DIMN] , right[2*DIMN] , level[2*DIMN];
int conf[DIMN];
void build_huffman_tree (){
    int pleaf,uleaf,pint,uint,ma,mb,tip , i;
    long long mini;
    pleaf = pint = 1;
    uint = uleaf = 0;
    for (i=1;i<=n;i++)
        leaf[++uleaf] = i;
    /// 2 deque uri , leaf si intern

    while (uleaf - pleaf + 1 + uint - pint + 1 > 1){
        /// alegi cele mai mici doua noduri
        mini = INF;
        ma = mb = 0;
        tip = 0;
        if (uleaf - pleaf + 1 >= 1){
            if (mini > fq[leaf[pleaf]] ){
                mini = fq[leaf[pleaf]];
                ma = leaf[pleaf];
                tip = 1;
            }
        }
        if (uint - pint + 1 >= 1){
            if (mini > fq[intern[pint]] ){
                mini = fq[intern[pint]];
                ma = intern[pint];
                tip = 0;
            }
        }

        if (tip == 1)
            pleaf++;
        else pint++;

        mini = INF;
        tip = 0;
        if (uleaf - pleaf + 1 >= 1){
            if (mini > fq[leaf[pleaf]] ){
                mini = fq[leaf[pleaf]];
                mb = leaf[pleaf];
                tip = 1;
            }
        }
        if (uint - pint + 1 >= 1){
            if (mini > fq[intern[pint]] ){
                mini = fq[intern[pint]];
                mb = intern[pint];
                tip = 0;
            }
        }

        if (tip == 1)
            pleaf++;
        else pint++;

        /// ai ales nodurile ma si mb
        nodes++;
        fq[nodes] = fq[ma] + fq[mb];
        sol+=fq[nodes];
        left[nodes] = ma;
        right[nodes] = mb; /// vecini
        intern[++uint] = nodes;
        //printf ("%d %lld %d %d\n" , nodes , fq[nodes] , ma , mb);
    }
    root = intern[uint];
}

void dfs (int nod){
    if (nod<=n){ /// FRUNZA
        for (int i = 1 ; i <= level[nod] ; i++)
            code[nod] = code[nod] + (1LL<<(level[nod] - i)) * conf[i];
        return;
    }
    level[right[nod]] = level[left[nod]] = 1 + level[nod];
    conf[level[nod]+1] = 0;
    dfs (left[nod]);
    conf[level[nod]+1] = 1;
    dfs (right[nod]);
}

int main()
{
    FILE *fin = fopen ("huffman.in","r");
    FILE *fout = fopen ("huffman.out","w");
    int i;
    fscanf (fin,"%d",&n);

    nodes = n;
    sol = 0;

    for (i=1;i<=n;i++){
        fscanf (fin,"%lld",&fq[i]);
    }

    build_huffman_tree ();

    dfs(root);

    fprintf (fout,"%lld\n",sol);

    for (i=1;i<=n;i++){
        fprintf (fout,"%d %lld\n",level[i] , code[i]);
    }
    return 0;
}