Cod sursa(job #2123583)

Utilizator tudor199G Tudor tudor199 Data 6 februarie 2018 13:30:27
Problema Coduri Huffman Scor 45
Compilator cpp Status done
Runda Arhiva educationala Marime 2.64 kb
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <fstream>

using namespace std;

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


class huffman{
public:
    huffman *lf, *rg;
    pair < int, unsigned long long > COD;
    unsigned long long times;
    huffman() : lf(NULL), rg(NULL), times(NULL) {}
    huffman(unsigned long long _times) : lf(NULL), rg(NULL), times(_times) {}
    huffman(unsigned long long _times, huffman *_lf, huffman *_rg) : lf(_lf), rg(_rg), times(_times) {}
};

unsigned long long dfs(huffman *now, int deep, unsigned long long code){
    if(!now ->lf){
        now ->COD = make_pair(deep, code);
        return 0;
    }
    unsigned long long rez = dfs(now ->lf, deep + 1, 2 * code) + dfs(now ->rg, deep + 1, 2 * code + 1);
    return now ->times + rez;
}

stack < pair < int, unsigned long long > > get_leafs(huffman* now){
    static stack < pair < int, unsigned long long > > leafs;
    queue< huffman* > Q;
    Q.push(now);
    while(!Q.empty()){
        now = Q.front();
        Q.pop();
        if(!now ->lf){
            leafs.push(now ->COD);
            continue;
        }
        Q.push(now ->lf);
        Q.push(now ->rg);
    }
    return leafs;
}

int main(){
    huffman *root, *lf, *rg, *now;
    auto cmp = [](huffman *left, huffman *right) { return (left ->times) > (right ->times);};
    priority_queue < huffman* , vector < huffman* >, decltype(cmp) > heap(cmp);
    queue <huffman *> Q1, Q2;
    int n, x;
    fin>>n;
    while(n--){
        fin>>x;
        heap.push(new huffman(x));
        Q1.push(new huffman(x));
    }
    root = Q1.front();
    Q1.pop();
    Q2.push(Q1.front());
    Q1.pop();
    while(!Q1.empty()){
        if(Q1.front() ->times < Q2.front() ->times){
            now = Q1.front();
            Q1.pop();
        }
        else{
            now = Q2.front();
            Q2.pop();
        }
        Q2.push(new huffman(root ->times + now ->times, root, now));
        if(!Q1.empty() && Q1.front() ->times < Q2.front() ->times){
            root = Q1.front();
            Q1.pop();
        }
        else{
            root = Q2.front();
            Q2.pop();
        }
    }
    while(!Q2.empty()){
        now = Q2.front();
        Q2.pop();
        Q2.push(new huffman(root ->times + now ->times, root, now));
        root = Q2.front();
        Q2.pop();
    }
    fout<<dfs(root, 0, 0)<<"\n";
    stack < pair < int, unsigned long long > > leafs = get_leafs(root);
    while(!leafs.empty()){
        fout<<leafs.top().first<<" "<<leafs.top().second<<"\n";
        leafs.pop();
    }
	return 0;
}