Cod sursa(job #2615134)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 13 mai 2020 18:30:23
Problema Coduri Huffman Scor 65
Compilator cpp-32 Status done
Runda Arhiva educationala Marime 2.44 kb
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

class InParser {
private:
	FILE *fin;
	char *buff;
	int sp;

	char read_ch() {
		++sp;
		if (sp == 4096) {
			sp = 0;
			fread(buff, 1, 4096, fin);
		}
		return buff[sp];
	}

public:
	InParser(const char* nume) {
		fin = fopen(nume, "r");
		buff = new char[4096]();
		sp = 4095;
	}

	InParser& operator >> (int &n) {
		char c;
		while (!isdigit(c = read_ch()) && c != '-');
		int sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}

	InParser& operator >> (long long &n) {
		char c;
		n = 0;
		while (!isdigit(c = read_ch()) && c != '-');
		long long sgn = 1;
		if (c == '-') {
			n = 0;
			sgn = -1;
		} else {
			n = c - '0';
		}
		while (isdigit(c = read_ch())) {
			n = 10 * n + c - '0';
		}
		n *= sgn;
		return *this;
	}
};

ofstream cout("huffman.out");

const int NMAX = 1e6;

int N, K;
int nodeWei[NMAX + 2];

struct node
{
    int index;
    long long wei;

    bool operator < (const node other) const
    {
        return wei > other.wei;
    }
};
priority_queue < node > pq;

int lenChar[NMAX + 2];
long long valChar[NMAX + 2];

vector < pair <int, bool> > g[2 * NMAX + 10];

void dfs(int node, int h, long long valTo)
{
    if(node <= N)
    {
        lenChar[node] = h;
        valChar[node] = valTo;
        return;
    }

    for(auto it : g[node])
        dfs(it.first, h + 1, (valTo << 1) + it.second);
}

int main()
{
    InParser cin("huffman.in");

    cin >> N;
    K = N;

    for(int i = 1; i <= N; i++)
    {
        cin >> nodeWei[i];
        pq.push({i, nodeWei[i]});
    }

    if(N == 1)
    {
        cout << nodeWei[1] << "\n1 0\n";
        return 0;
    }

    while(pq.size() > 1)
    {
        node f = pq.top();
        pq.pop();
        node s = pq.top();
        pq.pop();

        K++;
        g[K].push_back({f.index, 0});
        g[K].push_back({s.index, 1});

        long long sumWei = f.wei + s.wei;
        pq.push({K, sumWei});
    }

    dfs(K, 0, 0);

    long long totalSz = 0;
    for(int i = 1; i <= N; i++)
        totalSz = totalSz + 1LL * nodeWei[i] * lenChar[i];

    cout << totalSz << '\n';
    for(int i = 1; i <= N; i++)
        cout << lenChar[i] << ' ' << valChar[i] << '\n';

    return 0;
}