Pagini recente » Cod sursa (job #1842239) | Cod sursa (job #2708578) | Cod sursa (job #765193) | Cod sursa (job #2547220) | Cod sursa (job #2495716)
#include <cstdio>
#include <fstream>
#include <cstring>
using namespace std;
FILE *fin = fopen("huffman.in", "r");
FILE *fout = fopen("huffman.out", "w");
long long n, m, i, j, v[1000001], c[2000001], nr[2000001], w[1000001], nrW, SOL;
pair<long long, long long> H[2000001];
void dfs(int nod, int cod, int niv){
c[nod] = cod;
nr[nod] = niv;
if(H[nod].first != 0){
for(int i = 0;i<2;i++){
if(i == 0){
int vecin = H[nod].first;
dfs(vecin, (cod<<1), niv+1);
if(H[vecin].first == 0)
SOL += nr[vecin]*v[vecin];
}
else{
int vecin = H[nod].second;
dfs(vecin, (cod<<1) + 1, niv+1);
if(H[vecin].first == 0)
SOL += nr[vecin]*v[vecin];
}
}
}
}
int main(){
fscanf(fin, "%lld", &n);
for(i=1;i<=n;i++){
fscanf(fin, "%lld", &v[i]);
w[i] = 100000001;
}
i = j = 1;
m = n;
while(m < 2*n){
if(v[i] <= w[j] && i <= n && i+1 <=n && v[i+1] <= w[j]){
/// le iau pe primele doua primul sir
w[++nrW] = v[i]+v[i+1];
H[++m] = {i, i+1};
i += 2;
}
else
if((v[i] <= w[j] && i <= n && ( (i+1 <= n && v[i+1] > w[j]) || (i+1 > n) ))||(i <= n && v[i] > w[j] && ((j+1 < 2*n && w[j+1] > v[i])||(j+1 >= 2*n)))){ /// iau capetele celor doua siruri
w[++nrW] = v[i] + w[j];
H[++m] = {i, j+n};
i++, j++;
}
else
if(j+1 <= 2*n-1 && (i > n || (w[j] < v[i] && w[j+1] < v[i]))){
w[++nrW] = w[j] + w[j+1];
H[++m] = {j+n, j+n+1};
j += 2;
}
}
dfs(2*n-1, 0, 0);
fprintf(fout,"%lld\n", SOL);
for(i=1;i<=n;i++)
fprintf(fout,"%d %lld\n", nr[i], c[i]);
return 0;
}