Cod sursa(job #2886340)

Utilizator RobertuRobert Udrea Robertu Data 7 aprilie 2022 16:54:48
Problema Coduri Huffman Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.23 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fin("huffman.in");
ofstream fout("huffman.out");

queue<long long> noduri, noduriI;

struct Nod {
    long long val;
    int st = -1, dr = -1;
}v[2 * 1000000];

int lungime[1000001];
long long cod[1000001];

void dfs(int start, int l, long long c) {
    if( start == -1)
        return;

    if( v[start].st == -1 && v[start].dr == -1 ) {
        lungime[start] = l;
        cod[start] = c;
    }

    dfs(v[start].st, l + 1, c * 2);
    dfs(v[start].dr, l + 1, c * 2 + 1);
}

int main() {

    int n, aparitii, i;
    long long lg = 0;
    fin >> n;

    if( n > 100000) {
        ios::sync_with_stdio(false);
        cin.tie(0);
    }

    for(i = 0; i < n; i++) {
        fin >> v[i].val;
        noduri.push(i);
    }
    //  cout << "ok\n";

    while( !noduri.empty() ) {
        int a, b;
        
        if( noduriI.empty() ) {
            a = noduri.front();
            noduri.pop();
        } else if( !noduri.empty() && v[noduri.front()].val < v[noduriI.front()].val ) {
            a = noduri.front();
            noduri.pop();
        } else {
            a = noduriI.front();
            noduriI.pop();
        }

        if( noduriI.empty() ) {
            b = noduri.front();
            noduri.pop();
        } else if( !noduri.empty() && v[noduri.front()].val < v[noduriI.front()].val ) {
            b = noduri.front();
            noduri.pop();
        } else {
            b = noduriI.front();
            noduriI.pop();
        }

        lg += (v[a].val + v[b].val);
        noduriI.push(i);
        v[i].val = v[a].val + v[b].val;
        v[i].st = a;
        v[i].dr = b;
        i++;
    }

    while( noduriI.size() > 1 ) {
        int a, b;
        a = noduriI.front();
        noduriI.pop();
        b = noduriI.front();
        noduriI.pop();

        lg += (v[a].val + v[b].val);
        noduriI.push(i);
        v[i].val = v[a].val + v[b].val;
        v[i].st = a;
        v[i].dr = b;
        i++;
    }

    noduriI.pop();


    fout << lg << '\n';

    // for(i = 0; i < 2 * n - 1; i++)
    //     cout << v[i].val << " " << v[i].st << " " << v[i].dr << '\n';
    i--;
    dfs(i, 0, 0);

    for(i = 0; i < n; i++) 
        fout << lungime[i] << " " << cod[i] << '\n';
    
    return 0;
}