Pagini recente » Istoria paginii utilizator/filaret | Diferente pentru ciorna intre reviziile 141 si 142 | Cod sursa (job #487776) | Istoria paginii utilizator/victorulinici | Cod sursa (job #996970)
Cod sursa(job #996970)
#include <cstdio>
#include <fstream>
#define NMax 1000010
#define INF 4000000000000000000LL
using namespace std;
int n;
struct Nod
{
long long frecv;
int fiu[2];
};
Nod a[2*NMax];
int q[2][NMax], pr[2], ul[2];
int lg[NMax];
long long sol, b[NMax];
inline void Read()
{
FILE *f = fopen("huffman.in", "r");
fscanf(f, "%d", &n);
int i;
for (i=1; i<=n; ++i)
{
fscanf(f, "%lld", &a[i].frecv);
q[0][++ul[0]] = i;
}
fclose(f);
}
inline void DFS(int nod, long long numar, int nivel)
{
if (a[nod].fiu[0])
{
DFS(a[nod].fiu[0], numar<<1, nivel+1);
DFS(a[nod].fiu[1], (numar<<1)+1, nivel+1);
return ;
}
if (nod <= n)
{
lg[nod] = nivel;
b[nod] = numar;
}
}
inline void Solve()
{
int i, j, k, poz;
long long minim;
k = n;
pr[0] = pr[1] = 1;
while (pr[0] + pr[1] <= ul[0] + ul[1])
{
++k;
for (i = 0; i<2; ++i) /// pentru fiul stang si apoi cel drept
{
minim = INF;
for (j = 0; j<2; ++j) /// extrag minimul din cele 2 cozi
{
if (pr[j] <= ul[j] && a[q[j][pr[j]]].frecv < minim)
{
poz = j;
minim = a[q[j][pr[j]]].frecv;
}
}
a[k].fiu[i] = q[poz][pr[poz]];
a[k].frecv += minim;
++pr[poz];
}
sol += a[k].frecv;
q[1][++ul[1]] = k;
}
DFS(k, 0, 0);
}
inline void Write()
{
FILE *g = fopen("huffman.out", "w");
fprintf(g, "%lld\n", sol);
int i;
for (i=1; i<=n; ++i)
fprintf(g, "%d %lld\n", lg[i], b[i]);
fclose(g);
}
int main()
{
Read();
Solve();
Write();
return 0;
}