Pagini recente » Cod sursa (job #3293885) | Cod sursa (job #3293498)
#include <iostream>
#include <bits/stdc++.h>
#define VMAX 1000005
#define INF 1000000000000000000
#define int long long int
using namespace std;
ifstream fin ("huffman.in");
ofstream fout ("huffman.out");
vector<int> de_adg; // aici vor fi, in ordine, de la mare la mic, toate valorile nodurilor care trb adaugate in copac
queue<int> noduri,litere;
vector<int> valori_litere;
struct ap{
int lg, val;
int aparitii;
};
ap identifica[VMAX]; // valorile finale ale simbolurilor
int getmin() // returneaza nodul sau simbolul cu valoarea minima din cele ramase
{
int i=INF,j=INF;
if(noduri.size())
j=noduri.front();
if(litere.size())
i=litere.front();
if(j==INF)
{
de_adg.push_back(identifica[i].aparitii); // odata ales, il putem adauga in lista
litere.pop();
return identifica[i].aparitii;
}
else if(i==INF)
{
noduri.pop();
de_adg.push_back(j); // odata ales, il putem adauga in lista
return j;
}
if(identifica[i].aparitii<=j)
{
de_adg.push_back(identifica[i].aparitii);
litere.pop();
return identifica[i].aparitii;
}
else
{
noduri.pop();
de_adg.push_back(j);
return j;
}
}
void build()
{
// pentru a reconstrui solutia, vom face o parcurgere pe nivele, iar daca o valoarea este egala cu a unui caracter, o vom inlocui
int nr, mij;
queue<pair<int,int>> qq;
pair<int,int>nod;
qq.push({0,0});
while(de_adg.size()) // cat timp nu am mers prin fiecare valoare nod, nu am terminat parcurgerea
{
// valori_litere e sortat crescator, la fel ca de_adg
//deci stim ca urmatorul simbol cautat va fi ultimul simbol pe care nu l-am intalnit
//prima data cand intalnim o valoare din adg==un simbol, atribuim simbolului valoarea gasita, greedy
nod=qq.front();
qq.pop();
nr=de_adg.back();
de_adg.pop_back();
if(valori_litere.back()==nr) // am gasit aparitia unui caracter
{
valori_litere.pop_back();
identifica[valori_litere.size()].lg=nod.first;
identifica[valori_litere.size()].val=nod.second;
}
else // e un nod
{
qq.push({nod.first+1,nod.second*2});
qq.push({nod.first+1,nod.second*2+1});
}
}
}
signed main()
{
int n,m,i,j,k,t,q,nr;
fin>>n;
valori_litere.push_back(0);
for(i=1;i<=n;i++)
{
fin>>j;
valori_litere.push_back(j);
identifica[i].aparitii=j;
litere.push(i);
}
while(litere.size() + noduri.size()>1)
{
i = getmin();
j = getmin();
noduri.push(i+j);
}
de_adg.push_back(noduri.front());
build(); // vom reconstrui "arborele"
nr=0;
for(i=1;i<=n;i++)
{
nr+=identifica[i].aparitii*identifica[i].lg;
}
fout<<nr<<'\n';
for(i=1;i<=n;i++)
fout<<identifica[i].lg<<' '<<identifica[i].val<<'\n';
return 0;
}