Pagini recente » Cod sursa (job #693544) | Cod sursa (job #1791384) | Cod sursa (job #2497745) | Cod sursa (job #3283979) | Cod sursa (job #1321337)
//#include <fstream>
//#include <iostream>
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <queue>
using namespace std;
//ifstream in("huffman.in");
//ofstream out("huffman.out");
typedef long long int int64;
const int max_size = 1000005;
struct TreeNode {
int64 frequency;
int left_son, right_son;
TreeNode() : frequency(0), left_son(0), right_son(0) {}
};
struct symbol {
int frequency;
int64 position_tree;
symbol() : frequency(0), position_tree(0) {}
symbol(int64 frequency, int position_tree) :
frequency(frequency), position_tree(position_tree) {}
bool operator < (symbol &rhs) const {
return frequency < rhs.frequency;
}
};
int n;
int64 total_length;
TreeNode tree[2 * max_size];
queue<symbol> queue1, queue2;
symbol ExtractMin() {
symbol result;
if (queue1.empty()) {
result = queue2.front();
queue2.pop();
}
else if (queue2.empty()) {
result = queue1.front();
queue1.pop();
}
else if (queue1.front() < queue2.front()) {
result = queue1.front();
queue1.pop();
}
else {
result = queue2.front();
queue2.pop();
}
return result;
}
void AssignCodes(int node, int64 code, int length) {
if (tree[node].left_son) {
AssignCodes(tree[node].left_son, code << 1, length + 1);
AssignCodes(tree[node].right_son, (code << 1) + 1, length + 1);
return;
}
/*
Have to use frequency for code and left_son for length to stay in
memory limits.
*/
total_length += (length * tree[node].frequency);
tree[node].frequency = code;
tree[node].left_son = length;
}
int main() {
freopen("huffman.in", "r", stdin);
freopen("huffman.out", "w", stdout);
//in >> n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
//in >> tree[i].frequency;
scanf("%lld", &tree[i].frequency);
queue1.push(symbol(tree[i].frequency, i));
}
for (int i = n + 1; i < 2 * n; ++i) {
symbol x = ExtractMin();
symbol y = ExtractMin();
tree[i].frequency = x.frequency + y.frequency;
tree[i].left_son = y.position_tree;
tree[i].right_son = x.position_tree;
queue2.push(symbol(tree[i].frequency, i));
}
AssignCodes(2 * n - 1, 0, 0);
//out << total_length << '\n';
printf("%lld\n", total_length);
for (int i = 1; i <= n; ++i)
//out << tree[i].left_son << ' ' << tree[i].frequency << '\n';
printf("%d %lld\n", tree[i].left_son, tree[i].frequency);
return 0;
}