Pagini recente » Istoria paginii runda/vs | Atasamentele paginii Clasament oni2011_9_2 | Cod sursa (job #1221330) | Monitorul de evaluare | Cod sursa (job #609568)
Cod sursa(job #609568)
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
struct Nod
{
long long fr;
int c;
struct Nod *st,*dr;
};
Nod *R;
int n;
int M[1000002];
long long Cod[1000002],sol;
short nr[1000002];
queue <Nod *> Q1,Q2;
inline bool SortareHeap(Nod *A,Nod *B)
{
if(A->fr==B->fr)
return A->c>B->c;
return A->fr>B->fr;
}
inline void Citire()
{
int i,x;
freopen("huffman.in","r",stdin);
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&x);
M[i]=x;
Nod *aux=new Nod;
aux->c=i;
aux->fr=x;
aux->st=aux->dr=NULL;
Q1.push(aux);
}
}
inline Nod* ExtractMin()
{
Nod* minim=NULL;
if(!Q1.empty())
minim=Q1.front();
if(!Q2.empty())
{
if(minim)
{
if(minim->fr>Q2.front()->fr)
minim=Q2.front();
}
else
minim=Q2.front();
}
if(!Q1.empty())
{
if(minim==Q1.front())
Q1.pop();
else
Q2.pop();
}
else
Q2.pop();
return minim;
}
inline void Construire_Arbore_Huffman()
{
int i;
Nod *X,*Y;
for(i=1;i<n;i++)
{
//extrag succesiv doua elemente minime
X=ExtractMin();
Y=ExtractMin();
//unific arborii X si Y creand noul nod radacina Z
Nod *Z=new Nod;
Z->st=X;
Z->dr=Y;
Z->fr=X->fr+Y->fr;
Z->c=0;
//si il introduc in coada
Q2.push(Z);
}
//singurul nod ramas in coada este radacina arborelui Huffman
R=ExtractMin();
}
inline void Generare_Coduri_Huffman(Nod *r,long long cod,short lg)
{
if(r->c) //am ajuns la un nod terminal,deci am ajuns la un caracter si am codul lui
{
Cod[r->c]=cod;
nr[r->c]=lg;
sol=sol+lg*M[r->c];
return;
}
if(r->st)
Generare_Coduri_Huffman(r->st,(cod<<1),lg+1);
if(r->dr)
Generare_Coduri_Huffman(r->dr,(cod<<1)+1,lg+1);
}
void Afisare()
{
freopen("huffman.out","w",stdout);
int i;
long long lg=0;
for(i=1;i<=n;i++)
lg=lg+M[i]*nr[i];
printf("%lld\n",lg);
for(i=1;i<=n;i++)
printf("%d %lld\n",nr[i],Cod[i]);
}
int main()
{
Citire();
Construire_Arbore_Huffman();
Generare_Coduri_Huffman(R,0,0);
Afisare();
return 0;
}