Pagini recente » Cod sursa (job #3239378) | Cod sursa (job #1107487) | Cod sursa (job #1553286) | Istoria paginii runda/grigore-moisil-2017-clasa-9/clasament | Cod sursa (job #1801449)
#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;
}