Cod sursa(job #2210317)

Utilizator vendettaSalajan Razvan vendetta Data 6 iunie 2018 11:25:02
Problema Coduri Huffman Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include <bits/stdc++.h>

using namespace std;

#define mp make_pair
#define pb push_back
#define ll long long
int testsNumber = 1;
const int nmax = 1e6 + 6;

int n;
ll a[nmax];
pair<ll, ll> b[nmax];
set<pair<int, ll >> mySet;
vector<pair<int, int>> gf[2 * nmax];
ll total = 0;
void reset() {

}

pair<int, ll> getMin() {
	auto it = mySet.begin();
	mySet.erase(mySet.begin());
	return *it;
}

void dfs(int node, int lung, ll code) {
	bool flag = false;
	for (int i = 0; i < gf[node].size(); ++i) {
		flag = true;
		int vc = gf[node][i].first;
		int bit = gf[node][i].second;
		code = code * 2 + bit;
		dfs(vc, lung + 1, code);
	}

	if (!flag) {
		total += 1LL * lung * a[node];
		b[node] = mp(lung, code);
	}
}

void solve() {
	for (int i = 1; i <= n; ++i) {
		mySet.insert(mp(a[i], i));
	}

	int currNode = n;
	for (int i = 1; i < n; ++i) {
		pair<int, ll> x = getMin();
		auto y = getMin();
		++currNode;
		gf[currNode].pb(mp(x.second, 1));
		gf[currNode].pb(mp(y.second, 0));
		mySet.insert(mp(x.first + y.first, currNode));
	}

	dfs(currNode, 0, 0);
	cout << total << "\n";
	for (int i = 1; i <= n; ++i) {
		cout << b[i].first << " " << b[i].second << "\n";
	}
}

int main() {
	ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
	freopen("huffman.in", "r", stdin);
	freopen("huffman.out", "w", stdout);
	//freopen("test.err", "w", stderr);
	// cin >> testsNumber;
#endif

	for (int currTest = 1; currTest <= testsNumber; ++currTest) {
		cin >> n;
		for (int i = 1; i <= n; ++i) {
			cin >> a[i];
		}
		reset();
		solve();
	}

	return 0;
}