Cod sursa(job #1801449)

Utilizator rockerboyHutter Vince rockerboy Data 8 noiembrie 2016 23:49:45
Problema Coduri Huffman Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.64 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
#include <utility>
#include <list>
#include <iostream>
#include <cstdlib>

std::ifstream in ("huffman.in");
std::ofstream out("huffman.out");

struct node
{
    node *left, *right;
    int val;
    node() {left = right = NULL;}
    node(int v): val(v)
    {
        left = right = NULL;
    }
    node(int v, int t)
    {
        val = v+t;
        left = new node(v);
        right = new node(t);
    }
    ~node()
    {
        delete left;
        delete right;
    }
};

typedef std::vector<int> vec;

void input (vec& x)
{
    unsigned n, i;
    in >> n;
    x.resize (n);
    for (i=0; i<n; i++)
        in >> x[i];
}

void select_mins (std::queue<node*>& q1, std::queue<node*>& q2, node*& r1, node*& r2)
{
    if (!q1.empty() && q1.front()->val < q2.front()->val)
    {
        r1 = q1.front(); q1.pop();
        if (!q1.empty() && q1.front() < q2.front())
        {
            r2 = q1.front(); q1.pop();
        }
        else
        {
            r2 = q2.front(); q2.pop();
        }
    }
    else
    {
        r1 = q2.front(); q2.pop();
        if (!q1.empty() && q1.front() < q2.front())
        {
            r2 = q1.front(); q1.pop();
        }
        else
        {
            r2 = q2.front(); q2.pop();
        }
    }
}

node* build_tree (const vec& x)
{
    unsigned m1, m2;
    std::queue<node*> free, done;
    node *root, *lcurrent, *rcurrent;
    for (unsigned i=0; i<x.size(); i++) free.push (new node(x[i]));

    m1 = free.front()->val; free.pop();
    m2 = free.front()->val; free.pop();
    root = new node(m1, m2);
    done.push (root);

    while (free.size() + done.size() > 1)
    {
        select_mins (free, done, lcurrent, rcurrent);
        root = new node;
        root->val = lcurrent->val + rcurrent->val;
        root->left = lcurrent;
        root->right = rcurrent;
        done.push (root);
    }

    return root;
}

std::list< long long > sol[33];
long long dfs (node* root, long long code, int lvl)
{
    if (root->left == NULL)
    {
        sol[lvl].push_back (code);
        return root->val;
    }
    long long ret = 0;
    ret += dfs (root->left, (code<<1)+1, lvl+1);
    ret += dfs (root->right, (code<<1), lvl+1);
    return ret;
}

int main()
{
    vec data;
    input (data);
    node* root = build_tree (data);

    out << dfs (root, 0, 0) << "\n";

    for (int i=32; i>0; i--)
    {
        for (auto it=sol[i].begin(); it!=sol[i].end(); it++)
        {
            out << i << " " << (*it) << "\n";
        }
    }

    delete root;
}