Pagini recente » Cod sursa (job #3136378) | Cod sursa (job #2933664) | Cod sursa (job #2523943) | Cod sursa (job #3286700) | Cod sursa (job #3222384)
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream fin("huffman.in");
ofstream fout("huffman.out");
int n;
vector<int> a;
vector<pair<int, long long> > ans;
class Node {
public:
Node *left;
Node *right;
int freq;
Node() {
this->left = NULL;
this->right = NULL;
this->freq = 0;
}
Node(Node *left, Node *right) {
this->left = left;
this->right = right;
this->freq = left->freq + right->freq;
}
~Node() {}
};
class Leaf : public Node {
public:
int index;
Leaf(int index) {
Node();
this->index = index;
this->freq = a[index];
}
~Leaf() {}
};
queue<Node *> initial;
queue<Node *> intern;
long long int dfs(Node *root, int niv, long long cod)
{
if (!root->left && !root->right) {
Leaf *leaf = (Leaf *)root;
ans[leaf->index].first = niv;
ans[leaf->index].second = cod;
return 0LL;
}
long long ret = 1LL * root->freq;
if (root->left) {
ret += dfs(root->left, niv + 1, (cod << 1LL) | 0LL);
}
if (root->right) {
ret += dfs(root->right, niv + 1, (cod << 1LL) | 1LL);
}
return ret;
}
int main()
{
fin >> n;
a.reserve(n);
int x;
for (int i = 0; i < n; i++) {
fin >> x;
a.push_back(x);
}
initial.push(new Leaf(0));
initial.push(new Leaf(1));
int index = 2;
Node *min1 = NULL, *min2 = NULL;
while (!initial.empty() || intern.size() != 1) {
if (intern.empty()) {
min1 = initial.front();
initial.pop();
} else
if (initial.empty()) {
min1 = intern.front();
intern.pop();
} else {
if (initial.front()->freq < intern.front()->freq) {
min1 = initial.front();
initial.pop();
} else {
min1 = intern.front();
intern.pop();
}
}
if (intern.empty()) {
min2 = initial.front();
initial.pop();
} else
if (initial.empty()) {
min2 = intern.front();
intern.pop();
} else {
if (initial.front()->freq < intern.front()->freq) {
min2 = initial.front();
initial.pop();
} else {
min2 = intern.front();
intern.pop();
}
}
intern.push(new Node(min1, min2));
while (initial.size() < 2 && index < n) {
initial.push(new Leaf(index));
index++;
}
}
Node *root = intern.front();
intern.pop();
a.clear();
ans.resize(n);
fout << dfs(root, 0, 0LL) << "\n";
for (int i = 0; i < n; i++)
fout << ans[i].first << " " << ans[i].second << "\n";
fin.close();
fout.close();
return 0;
}