Pagini recente » Cod sursa (job #1504414) | Cod sursa (job #1750334) | Cod sursa (job #202536) | Statistici Radu Vlad Ilia (raduilia) | Cod sursa (job #1307980)
#include <cstdint>
#include <algorithm>
#include <fstream>
#include <vector>
#include <map>
using namespace std;
struct Node {
uint64_t weight;
int left;
int right;
Node(uint64_t weight, int left = 0, int right = 0)
: weight {weight}, left {left}, right {right}
{}
};
inline
int pop(const vector<Node>& Q, int& l1, const int r1, int& l2, const int r2) {
int res;
if (l1 < r1) {
if (l2 < r2) {
if (Q[l1].weight < Q[l2].weight) res = l1++;
else res = l2++;
}
else res = l1++;
}
else res = l2++;
return res;
}
uint64_t df(
int node, map<int, vector<uint64_t>>& alphabet,
const vector<Node>& data, uint64_t rep = 0, int h = 0) {
if (data[node].left)
return df(data[node].left, alphabet, data, rep << 1, h + 1) +
df(data[node].right, alphabet, data, (rep << 1) + 1, h + 1);
alphabet[h].push_back(rep);
return data[node].weight * h;
}
int main() {
ifstream fin("huffman.in");
ofstream fout("huffman.out");
int n; fin >> n;
vector<Node> Q; Q.push_back(0);
for (uint64_t x; n--; ) {
fin >> x;
Q.push_back(Node(x));
}
int l1 = 1, r1 = Q.size();
int l2 = r1, r2 = r1;
for (int l, r; r1 - l1 + r2 - l2 > 1;) {
l = pop(Q, l1, r1, l2, r2);
r = pop(Q, l1, r1, l2, r2);
Q.push_back(Node(Q[l].weight + Q[r].weight, l, r));
++r2;
}
map<int, vector<uint64_t>> alphabet;
fout << df(l2, alphabet, Q) << '\n';
for (auto it = alphabet.rbegin(); it != alphabet.rend(); ++it)
for (auto rep : it->second)
fout << (it->first) << ' ' << rep << '\n';
return 0;
}