Pagini recente » Cod sursa (job #2579479) | Cod sursa (job #158109) | Cod sursa (job #2352655) | Cod sursa (job #1003916) | Cod sursa (job #2375815)
#include <fstream>
#include <queue>
using namespace std;
ifstream fin("huffman.in");
ofstream fout("huffman.out");
queue <int> q,p;
long long v[2000005];
long long ok=1,nrnoduri,a,b,n,x1,x2;
long long cod[200005];
char decarefiu[2000005];
int tata[2000005],lung[2000005];
int main()
{
fin>>n;//citesc numarul de simboluri
nrnoduri=n;
for(int i=1;i<=n;i++){
fin>>v[i];//citesc nr aparitii simbol
q.push(i);//le bag in coada
}
while(ok){
if(q.empty()|| p.empty()){//q tine nodurile initiale , p tine nodurile create prin imbinare
if(q.empty())//daca q e gol ne oucpam acum doar de coada p
{
a = p.front();
p.pop();
if(p.empty())//daca si p e gol atunci e gata algo
{
ok=0;
continue;
}
b=p.front();
p.pop();
}
else
{
a=q.front();//extragem primele 2 cele mai mici
q.pop();
if(q.empty())
{
ok=0;
continue;
}
b=q.front();
q.pop();
}
}
else{//daca avem si noduri in q si noduri imbinate in p verificam daca le putem adauga si pe cele din p
x1=q.front();
x2=p.front();
if(v[x1]<v[x2]){
a=x1;
q.pop();
if(q.empty())//daca nu mai avem ce noduri din q sa verificam pentru o potentiala imbinare
{
b=x2;
p.pop();
}
else
{
x1=q.front();
if(v[x1]<v[x2])
{
b = x1;
q.pop();
}
else
{
b=x2;
p.pop();
}
}
}
else
{
a=x2;
p.pop();
if(p.empty())
{
b=x1;
q.pop();
}
else
{
x2=p.front();
if(v[x1]<v[x2])
{
b = x1;
q.pop();
}
else
{
b=x2;
p.pop();
}
}
}
}
++ nrnoduri;//crestem numarul nodurilor obtinute prin imbinare
tata[a]=nrnoduri;//spunem pt a si b actual nodul al catelea imbinat este tatal
decarefiu[a]=0;//spunem daca e fiu de stanga/dreapta
decarefiu[b]=1;
tata[b]=nrnoduri;
v[nrnoduri] = v[a]+v[b];//combinam frecventele
p.push(nrnoduri);//bagam in coada nodurilor obtinute prin imbinare
}
a=0;
for(int k=n+1;k<=nrnoduri;k++){
a+=v[k];//adunam frecventele totale ale nodurilor obtinute prin imbinare ca sa aflam lungimea
}
fout<<a<<'\n';
for(int i=1;i<=n;i++){
a=i;
b=0;
while(tata[a]!=0)//obtinem codul simbolului al i-lea parcurgand arborele lui Huffman
{
lung[i]++;
cod[lung[i]]=decarefiu[a];
a=tata[a];
}
a=0;
for(int j=lung[i];j>=1;--j)
a=a*2+cod[j];//obtinem scrierea in baza 10
fout<<lung[i]<<" "<<a<<'\n';
}
return 0;
}