Pagini recente » Cod sursa (job #1062979) | Cod sursa (job #269570) | Cod sursa (job #419949) | Cod sursa (job #39328) | Cod sursa (job #1802045)
#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;
}