Pagini recente » Cod sursa (job #321612) | Cod sursa (job #266431) | Cod sursa (job #2763044) | Cod sursa (job #2315503) | Cod sursa (job #2217875)
#include <fstream>
#include <queue>
using namespace std;
ifstream in("huffman.in");
ofstream out("huffman.out");
const int MAXC = 1000001;
struct nod
{
int left, right;
};
nod arb[MAXC * 2];
int N, lgcod[MAXC];
long long fr[MAXC * 2], cod[MAXC], lgtext;
queue<int> Q1; //contine nodurile initiale
queue<int> Q2; //contine nodurile interne
void rsd(int nod, int K, long long val)
{
if(arb[nod].left)
{
rsd(arb[nod].left, K + 1, (val << 1LL));
rsd(arb[nod].right, K + 1, (val << 1LL) + 1LL);
}
else
{
lgcod[nod] = K;
cod[nod] = val;
}
}
void get_fr(int &x)
{
if (Q1.empty())
{
x = Q2.front();
Q2.pop();
}
else if (Q2.empty())
{
x = Q1.front();
Q1.pop();
}
else if (fr[Q1.front()] < fr[Q2.front()])
{
x = Q1.front();
Q1.pop();
}
else
{
x = Q2.front();
Q2.pop();
}
}
void citire_frecv()
{
///FRECVENTELE SUNT IN ORDINE CRESCATOARE, DECI NU MAI AVEM NEVOIE DE HEAP, FOLOSIM QUEUE
in >> N;
int x;
for(int i = 1; i <= N; i++)
{
in >> x;
fr[i] = (long long) x;
Q1.push(i);
}
}
void Huffman()
{
int nrnod = N;
while(Q1.size() + Q2.size() >= 2)
{
int left, right;
get_fr(left);
get_fr(right);
nrnod++;
Q2.push(nrnod);
fr[nrnod] = fr[left] + fr[right];
lgtext += fr[nrnod];
arb[nrnod].left = left;
arb[nrnod].right = right;
}
///nrnod este radacina arborelui Huffman, pe care il parcurgem si aflam codurile Huffman ale caracterelor
rsd(nrnod, 0, 0);
}
void afisare()
{
out << lgtext << '\n';
for(int i = 1; i <= N; i++)
out << lgcod[i] << ' ' << cod[i] << '\n';
}
int main()
{
citire_frecv();
Huffman();
afisare();
return 0;
}