Pagini recente » Cod sursa (job #3293337) | Cod sursa (job #3280732) | Cod sursa (job #3285672) | Cod sursa (job #3285517) | Cod sursa (job #3272775)
#define MAX_N 1000000
#include <fstream>
#include <memory>
#include <queue>
using namespace std;
using i64 = long long;
ifstream fin("huffman.in");
ofstream fout("huffman.out");
struct node {
i64 w;
i64 code;
short depth;
int index;
shared_ptr<node> next[2];
constexpr bool operator>(const node &other) const {
return this->w > other.w;
}
};
vector<node> leaves;
priority_queue<node, vector<node>, greater<node>> nodes;
int main() {
int n;
fin >> n;
leaves = vector<node>(n + 1);
for (int i = 1; i <= n; i++) {
node new_node;
fin >> new_node.w;
new_node.next[0] = nullptr;
new_node.next[1] = nullptr;
new_node.index = i;
nodes.push(new_node);
}
shared_ptr<node> root = nullptr;
while (!nodes.empty()) {
node first = nodes.top();
nodes.pop();
if (nodes.empty()) {
root = make_shared<node>(first);
break;
}
node second = nodes.top();
nodes.pop();
node father = {first.w + second.w, 0, 0, 0, make_shared<node>(first),
make_shared<node>(second)};
root = make_shared<node>(father);
nodes.push(father);
}
queue<node> q;
q.push(*root);
i64 sum = 0;
while (!q.empty()) {
node crt = q.front();
q.pop();
if (crt.next[0]) {
crt.next[0]->depth = crt.depth + 1;
crt.next[0]->code = crt.code * 2;
q.push(*crt.next[0]);
crt.next[1]->depth = crt.depth + 1;
crt.next[1]->code = crt.code * 2 + 1;
q.push(*crt.next[1]);
} else {
sum += crt.depth * crt.w;
leaves[crt.index] = crt;
}
}
fout << sum << '\n';
for (size_t i = 1; i < leaves.size(); i++) {
const auto &node = leaves[i];
fout << node.depth << ' ' << node.code << '\n';
}
return 0;
}