Cod sursa(job #1802045)

Utilizator rockerboyHutter Vince rockerboy Data 9 noiembrie 2016 20:17:56
Problema Coduri Huffman Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 3.63 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;
    long long val;
    node() {left = right = NULL;}
    node(long long v): val(v)
    {
        left = right = NULL;
    }
    node(long long v, long long t)
    {
        val = v+t;
        left = new node(v);
        right = new node(t);
    }
    ~node()
    {
        delete left;
        delete right;
    }
};

typedef std::vector<long long> 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() && (q2.empty() || q1.front()->val < q2.front()->val))
        {
            r2 = q1.front(); q1.pop();
        }
        else
        {
            r2 = q2.front(); q2.pop();
        }
    }
    else
    {
        r1 = q2.front(); q2.pop();
        if (!q1.empty() && (q2.empty() || q1.front()->val < q2.front()->val))
        {
            r2 = q1.front(); q1.pop();
        }
        else
        {
            r2 = q2.front(); q2.pop();
        }
    }
}
/*
std::vector< std::list<long long> > ls;
void dbgtree (node* x, unsigned lvl=1)
{
    if (x == NULL) return;

    if (lvl == 1)
    {
        ls.clear();
        ls.resize(1);
    }

    if (lvl >= ls.size())
    {
        ls.push_back (std::list<long long>());
    }
    ls[lvl].push_back (x->val);
    dbgtree (x->left, lvl+1);
    dbgtree (x->right, lvl+1);

    if (lvl == 1)
    {
        std::cout << "Current state: \n";
        for (unsigned i=1; i<ls.size(); i++)
        {
            std::cout << i << ":  ";
            for (auto it=ls[i].begin(); it!=ls[i].end(); it++)
            {
                std::cout << *it << " ";
            }
            std::cout << "\n";
        }
        std::cout << "\n";
    }
}
*/
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)
    {
        //dbgtree (root);
        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;
}

const int SOLSIZE = 65;
std::list< long long > sol[SOLSIZE];
long long dfs (node* root, long long code, long lvl)
{
    if (root->left == NULL)
    {
        sol[lvl].push_back (code);
        //return root->val;
        return lvl*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 = new vec;
    input (*data);
    node* root = build_tree (*data);
    delete data;

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

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

    //delete root;
}