Pagini recente » Cod sursa (job #1561184) | Monitorul de evaluare | Cod sursa (job #1975766) | Cod sursa (job #1014809) | Cod sursa (job #821129)
Cod sursa(job #821129)
#include<fstream>
using namespace std;
#define Nmax 1000100
struct graf {
long long val;
int fiu[3];
} G[Nmax * 2];
struct heap {
long long val, ind;
} H[Nmax * 2];
long long B[Nmax], lg[Nmax], rez;
int N, Q;
void Heap_Up(int k) {
while(k>1 && H[k].val<H[k/2].val) {
long long aux;
aux = H[k].val;
H[k].val = H[k/2].val;
H[k/2].val = aux;
aux = H[k].ind;
H[k].ind = H[k/2].ind;
H[k/2].ind = aux;
k/=2;
}
}
void insert(long long val, long long ind) {
H[++Q].val = val;
H[Q].ind = ind;
Heap_Up(Q);
}
void Heap_Down(int k) {
int son = k;
if(2*k<=Q && H[2*k].val<H[son].val)
son = 2*k;
if(2*k+1<=Q && H[2*k+1].val<H[son].val)
son = 2*k+1;
if(son!=k) {
long long aux;
aux = H[k].val;
H[k].val = H[son].val;
H[son].val = aux;
aux = H[k].ind;
H[k].ind = H[son].ind;
H[son].ind = aux;
Heap_Down(son);
}
}
void erase() {
int k = 1;
H[k].val = H[Q].val;
H[k].ind = H[Q].ind;
Q--;
if(k>1 && H[k].val<H[k/2].val)
Heap_Up(k);
else
Heap_Down(k);
}
void read_data() {
ifstream f("huffman.in");
int i;
f>>N;
for(i=1; i<=N; i++) {
f>>G[i].val;
insert(G[i].val, i);
}
f.close();
}
void DF(int poz, long long cod, long long nivel) {
// fiind arbore strict e clar ca daca are un fiu il va avea si pe cel de-al doilea
if(G[poz].fiu[1]) {
DF(G[poz].fiu[1], cod*2, nivel+1);
DF(G[poz].fiu[2], cod*2+1, nivel+1);
return;
}
lg[poz] = nivel;
B[poz] = cod;
// adunam in rez suma costurilor nodurilor interne
rez = (rez + lg[poz] * G[poz].val);
}
void solve() {
int M, i, cost, nod;
M = N;
// cand in Heap ramane o singura valoare inseamna ca s-au adunat toate valorile
while(Q != 1) {
++M;
// unim cele mai mici 2 noduri existente in Heap
for(i=1; i<=2; ++i) {
cost = H[1].val;
nod = H[1].ind;
erase();
G[M].val += cost;
G[M].fiu[i] = nod;
}
/* introducem in Heap noul nod creat care are ca fii cele 2 noduri de cost minim si
ca valoare suma valorilor celor 2 noduri*/
insert(G[M].val, M);
}
DF(M, 0, 0);
}
void print_rez() {
int i;
ofstream g("huffman.out");
g<<rez<<"\n";
for(i=1; i<=N; ++i)
g<<lg[i]<<" "<<B[i]<<"\n";
g.close();
}
int main() {
read_data();
solve();
print_rez();
return 0;
}