Pagini recente » Borderou de evaluare (job #2116711) | Cod sursa (job #102340) | Cod sursa (job #1931640) | Monitorul de evaluare | Cod sursa (job #1134145)
#include <queue>
#include <cstdio>
using namespace std;
const int MAX_N = 1000002;
const int SIGMA = 2;
struct Node {
int ind;
int sons[SIGMA];
long long val;
};
int N;
int frequency[MAX_N];
queue < int > a, b;
long long ans;
pair < int, long long > sol[MAX_N];
Node v[2 * MAX_N];
void DFS(Node node, long long code, int lv) {
if(node.sons[0]) {
DFS(v[node.sons[0]], code * 2, lv + 1);
DFS(v[node.sons[1]], code * 2 + 1, lv + 1);
}
else {
sol[node.ind] = make_pair(lv, code);
ans += (long long) lv * frequency[node.ind];
}
}
inline int getMin() {
int ret = 0;
if(a.empty()) {
ret = b.front();
b.pop();
}
else if(b.empty()) {
ret = a.front();
a.pop();
}
else if(v[a.front()].val < v[b.front()].val) {
ret = a.front();
a.pop();
}
else {
ret = b.front();
b.pop();
}
return ret;
}
int main() {
freopen("huffman.in", "r", stdin);
freopen("huffman.out", "w", stdout);
scanf("%d", &N);
Node temp;
temp.sons[0] = temp.sons[1] = 0;
for(int i = 1; i <= N; ++i) {
scanf("%d", &frequency[i]);
temp.val = frequency[i];
temp.ind = i;
v[i] = temp;
a.push(i);
}
int p = N + 1;
Node node, temp1, temp2;
while(!a.empty() || b.size() > 1) {
temp1 = v[getMin()];
temp2 = v[getMin()];
node.val = temp1.val + temp2.val;
node.ind = p;
node.sons[0] = temp1.ind, node.sons[1] = temp2.ind;
v[p] = node;
++p;
b.push(node.ind);
}
DFS(node, 0, 0);
printf("%lld\n", ans);
for(int i = 1; i <= N; ++i)
printf("%d %lld\n", sol[i].first, sol[i].second);
fclose(stdin);
fclose(stdout);
return 0;
}