Pagini recente » Cod sursa (job #2551369) | Cod sursa (job #1431264) | Rezultatele filtrării | Rezultatele filtrării | Cod sursa (job #3301181)
#include <algorithm>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#include <fstream>
#include <cstring>
using namespace std;
#define fast_io ios::sync_with_stdio(0); cin.tie(0); do{}while(0)
typedef long long ll;
ifstream fin("huffman.in");
ofstream fout("huffman.out");
const int MAXN = 1e6 + 5;
int n;
long long frv[MAXN];
queue<int> realKeys;
queue<int> virtualKeys;
vector<int> graph[MAXN * 2];
pair<long long, long long> ans[MAXN];
int id = 0;
void ReadData() {
fin >> n;
for (int i = 0; i < n; i++) {
fin >> frv[i];
realKeys.push(id++);
}
}
int ExtractMinKey() {
int entry;
if (virtualKeys.empty()) {
entry = realKeys.front();
realKeys.pop();
} else if (realKeys.empty()) {
entry = virtualKeys.front();
virtualKeys.pop();
} else if (frv[realKeys.front()] < frv[virtualKeys.front()]) {
entry = realKeys.front();
realKeys.pop();
} else {
entry = virtualKeys.front();
virtualKeys.pop();
}
return entry;
}
int BuildHuffman() {
while (realKeys.size() + virtualKeys.size() > 1) {
int a = ExtractMinKey();
int b = ExtractMinKey();
graph[id].push_back(a);
graph[id].push_back(b);
frv[id] = frv[a] + frv[b];
virtualKeys.push(id);
id++;
}
return virtualKeys.front();
}
void BuildAnswer(long long node, long long height, long long value) {
if (node < n) {
ans[node] = {height, value};
return;
}
BuildAnswer(graph[node][0], height + 1, value << 1);
BuildAnswer(graph[node][1], height + 1, (value << 1) | 1);
}
void Solve() {
long long root = BuildHuffman();
BuildAnswer(graph[root][0], 1, 0);
BuildAnswer(graph[root][1], 1, 1);
long long sum = 0;
for (int i = 0; i < n; i++) {
sum += ans[i].first * frv[i];
}
fout << sum << '\n';
for (int i = 0; i < n; i++) {
fout << ans[i].first << ' ' << ans[i].second << '\n';
}
}
int main() {
ReadData();
Solve();
return 0;
}