Pagini recente » Cod sursa (job #2095026) | Cod sursa (job #144361) | Cod sursa (job #1367273) | Cod sursa (job #1973904) | Cod sursa (job #2955440)
// Huffman cu doua cozi, O(n)
#include <fstream>
#include <iostream>
#include <queue>
using namespace std;
#define MAXN 1000100
struct NOD {
long long v;
int f[2]; // fiul stang, fiul drept
} nod[2 * MAXN];
int n, l[MAXN];
queue<int> q[2]; // coada frunzelor, coada nodurilor interioare
long long b[MAXN], m, lt;
ifstream fin("huffman.in");
ofstream fout("huffman.out");
void walk_tree(long poz, long long cod, long nivel) {
if (nod[poz].f[0]) { // nod interior
walk_tree(nod[poz].f[0], cod * 2, nivel + 1);
walk_tree(nod[poz].f[1], cod * 2 + 1, nivel + 1);
return;
}
else { // frunza
l[poz] = nivel; // lungimea codului
b[poz] = cod;
}
}
void build_tree() {
int iqmin;
long long m;
for (int k = n + 1; k <= 2 * n - 1; k++) {
for (int fiu = 0; fiu <= 1; fiu++) {
m = 1e18;
for (int iq = 0; iq <= 1; iq++) {
if (not q[iq].empty())
if (nod[q[iq].front()].v < m) {
iqmin = iq;
m = nod[q[iq].front()].v;
}
}
nod[k].v += nod[q[iqmin].front()].v;
cout << nod[q[iqmin].front()].v << endl;
nod[k].f[fiu] = q[iqmin].front();
q[iqmin].pop();
}
lt += nod[k].v;
q[1].push(k);
}
}
int main() {
fin >> n;
for (int i = 1; i <= n; i++) {
fin >> nod[i].v;
q[0].push(i);
}
build_tree();
walk_tree(2 * n - 1, 0, 0);
fout << lt << '\n';
for (int i = 1; i <= n; i++) {
fout << l[i] << ' ' << b[i] << '\n';
}
return 0;
}