Pagini recente » Cod sursa (job #721339) | Cod sursa (job #370923) | Rezultatele filtrării | Cod sursa (job #1051669) | Cod sursa (job #3301178)
#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;
struct Entry {
long long id;
long long frv;
bool operator <(const Entry& other) const {
return frv > other.frv;
}
};
long long n;
long long frv[MAXN];
long long parents[MAXN * 2];
long long height[MAXN * 2];
queue<Entry> realKeys;
queue<Entry> virtualKeys;
vector<int> graph[MAXN * 2];
pair<long long, long long> ans[MAXN];
long long id = 0;
void ReadData() {
fin >> n;
for (int i = 0; i < n; i++) {
fin >> frv[i];
realKeys.push({id++, frv[i]});
}
}
Entry ExtractMinKey() {
Entry entry;
if (virtualKeys.empty()) {
entry = realKeys.front();
realKeys.pop();
} else if (realKeys.empty()) {
entry = virtualKeys.front();
virtualKeys.pop();
} else if (realKeys.front().frv < virtualKeys.front().frv) {
entry = realKeys.front();
realKeys.pop();
} else {
entry = virtualKeys.front();
virtualKeys.pop();
}
return entry;
}
int BuildHuffman() {
while (realKeys.size() + virtualKeys.size() > 1) {
Entry a = ExtractMinKey();
Entry b = ExtractMinKey();
graph[id].push_back(a.id);
graph[id].push_back(b.id);
virtualKeys.push({id, a.frv + b.frv});
id++;
}
return virtualKeys.front().id;
}
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;
}