Pagini recente » Cod sursa (job #2590952) | Cod sursa (job #2235939) | Cod sursa (job #516745) | Cod sursa (job #135052) | Cod sursa (job #1997232)
#include<cstdio>
#include<queue>
const int NMAX = 1000002;
using namespace std;
class node
{
public:
node(const long long value) : left(nullptr), right(nullptr)
{
this->value = value;
}
node *left, *right;
long long value;
};
class leaf_node: public node
{
public:
leaf_node(const long long val, const int sym) : node(val)
{
this->symbol = sym;
}
int symbol;
};
struct predicate
{
bool operator () (const node *left, const node *right)
{
return left->value > right->value;
}
};
int N;
queue<node*> Q;
queue<leaf_node*> lQ;
int len[NMAX];
unsigned long long code[NMAX];
int depth;
unsigned long long ans_sum;
void dfs(node* current, unsigned long long path = 0)
{
if (current->left == nullptr && current->right == nullptr)
{
int sym = ((leaf_node*)current)->symbol;
len[sym] = depth;
code[sym] = path;
return;
}
ans_sum += current->value;
if (current->left != nullptr) {
++depth;
dfs(current->left, path * 2);
--depth;
}
if (current->right != nullptr) {
++depth;
dfs(current->right, path * 2 + 1);
--depth;
}
}
node* pop_min ()
{
node* ans;
if (lQ.empty()) {
ans = Q.front();
Q.pop();
return ans;
}
if (Q.empty()) {
ans = lQ.front();
lQ.pop();
return ans;
}
node* lqf = lQ.front();
node* qf = Q.front();
if (lqf->value <= qf->value)
{
lQ.pop();
return lqf;
}
else
{
Q.pop();
return qf;
}
}
int main()
{
freopen("huffman.in", "r", stdin);
freopen("huffman.out", "w", stdout);
int val;
scanf("%d", &N);
for (int i = 0; i < N; ++i)
{
int val;
scanf("%d", &val);
leaf_node* leaf = new leaf_node(val ,i);
lQ.push(leaf);
}
while(!lQ.empty() || Q.size() != 1)
{
node* first = pop_min();
node* second = pop_min();
node* parent = new node(first->value + second->value);
parent->left = first;
parent->right = second;
Q.push(parent);
}
dfs(Q.front());
printf("%llu\n", ans_sum);
for (int i = 0; i < N; ++i) {
printf("%d %llu\n", len[i], code[i]);
}
}