Pagini recente » Cod sursa (job #207700) | Cod sursa (job #1921918) | Cod sursa (job #2843775) | Cod sursa (job #956725) | Cod sursa (job #904147)
Cod sursa(job #904147)
#include <fstream>
#include <iostream>
#include <string>
#include <queue>
#include <vector>
using namespace std;
const string file = "huffman";
const string infile = file + ".in";
const string outfile = file + ".out";
#define NMAX 1000000
int N;
int A[NMAX];
int l[NMAX];
long long lg;
long long bi[NMAX];
struct HNod
{
long long sum;
int i;
HNod *s;
HNod *d;
HNod(long long sum, int i)
{
this->i = i;
this->sum = sum;
}
HNod(HNod* s, HNod* d)
{
this->i = -1;
this->s = s;
this->d = d;
this->sum = s->sum + d->sum;
}
};
HNod* NIL = new HNod((1LL<<60), -1);
queue<HNod*> q[2];
void citire()
{
fstream fin(infile.c_str(), ios::in );
char buffer[6 * 1024];
int i = -1 ;
int currentNumber = 0;
while(fin.good())
{
fin.read(buffer, 6 * 1024);
int count = fin.gcount();
for(int j = 0; j < count; j++)
{
if (isdigit(buffer[j]) != 0)
{
currentNumber *= 10;
currentNumber += buffer[j] - '0';
}
else
{
if(i == -1)
{
N = currentNumber;
currentNumber = 0;
i++;
}
else
{
A[i] = currentNumber;
q[0].push(new HNod(A[i], i));
i++;
currentNumber = 0;
}
}
}
}
if(currentNumber != 0)
{
A[i] = currentNumber;
q[0].push(new HNod(A[i], i));
i++;
}
fin.close();
}
HNod* extractMin()
{
HNod* min = 0;
HNod* min1 = q[0].empty() ? NIL : q[0].front();
HNod* min2 = q[1].empty() ? NIL : q[1].front();
if(min1->sum < min2->sum)
{
min = min1;
q[0].pop();
}
else
{
min = min2;
q[1].pop();
}
return min;
}
void dfs(int nivel, HNod* nod, long long b)
{
if(nod->i != -1)
{
l[nod->i] = nivel;
bi[nod->i] = b;
}
else
{
dfs(nivel + 1, nod->s, b << 1 );
dfs(nivel + 1, nod->d, (b << 1) + 1);
}
}
void solve()
{
while(q[0].empty() == false || q[1].empty()==false)
{
HNod* min1 = extractMin();
HNod* min2 = extractMin();
q[1].push(new HNod(min1, min2));
if(q[0].empty() && q[1].size() == 1)
break;
}
dfs(0, q[1].front(), 0);
for(int i = 0; i < N; i++)
{
lg += A[i] * l[i];
}
}
void afisare()
{
fstream fout(outfile.c_str(), ios::out);
fout << lg << "\n";
for(int i = 0; i < N; i++)
{
fout << l[i] << " " << bi[i] << "\n";
}
fout.close();
}
int main()
{
citire();
solve();
afisare();
}