Pagini recente » Cod sursa (job #2548936) | Cod sursa (job #2313382) | Cod sursa (job #112197) | Cod sursa (job #2521641) | Cod sursa (job #3222351)
#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 index;
int freq;
Node(int index) {
this->index = index;
this->left = NULL;
this->right = NULL;
this->freq = a[index];
}
Node(Node *left, Node *right) {
this->left = left;
this->right = right;
this->freq = left->freq + right->freq;
this->index = -1;
}
~Node() {}
};
queue<Node *> initial;
queue<Node *> intern;
long long int dfs(Node *root, int niv, long long cod)
{
if (!root->left && !root->right) {
ans[root->index].first = niv;
ans[root->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);
ans.resize(n);
int x;
for (int i = 0; i < n; i++) {
fin >> x;
a.push_back(x);
}
initial.push(new Node(0));
initial.push(new Node(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 Node(index));
index++;
}
}
Node *root = intern.front();
intern.pop();
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;
}