Cod sursa(job #1229650)

Utilizator Ionut228Ionut Calofir Ionut228 Data 17 septembrie 2014 21:30:06
Problema Coduri Huffman Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.03 kb
#include <fstream>
#include <queue>

using namespace std;

ifstream fin("huffman.in");
ofstream fout("huffman.out");

int N;
long long lgnow, bsnow, result;
long long val[2000002], lg[2000002], bs[2000002];
int V[2000002][2];
queue<int> Qnodinit, Qnod;

void Dfs(int nodnow)
{
    if (nodnow <= N)
    {
        lg[nodnow] = lgnow;
        bs[nodnow] = bsnow;
        return;
    }

    ++lgnow;
    bsnow = bsnow * 2;
    Dfs(V[nodnow][0]);
    bsnow = bsnow + 1;
    Dfs(V[nodnow][1]);
    bsnow = bsnow / 2;
    --lgnow;
}

void solve()
{
    int nodnow = N;

    ++nodnow;
    for (int i = 0; i < 2; ++i)
    {
        V[nodnow][i] = Qnodinit.front();
        val[nodnow] += val[Qnodinit.front()];
        Qnodinit.pop();
    }
    Qnod.push(nodnow);

    while (!Qnodinit.empty() || !Qnod.empty())
    {
        ++nodnow;

        if (Qnodinit.empty())
        {
            for (int i = 0; i < 2; ++i)
            {
                V[nodnow][i] = Qnod.front();
                val[nodnow] += val[Qnod.front()];
                Qnod.pop();
            }
            if (!Qnod.empty()) Qnod.push(nodnow);
            continue;
        }

        for (int i = 0; i < 2; ++i)
        {
            int now;
            if (val[Qnodinit.front()] <= val[Qnod.front()])
            {
                now = Qnodinit.front();
                Qnodinit.pop();
            }
            else
            {
                now = Qnod.front();
                Qnod.pop();
            }

            V[nodnow][i] = now;
            val[nodnow] += val[now];
        }
        Qnod.push(nodnow);
    }

    Dfs(nodnow);
}

int main()
{
    fin >> N;
    for (int i = 1; i <= N; ++i)
    {
        fin >> val[i];
        Qnodinit.push(i);
    }

    solve();

    for (int i = 1; i <= N; ++i)
        result += val[i] * lg[i];
    fout << result << '\n';
    for (int i = 1; i <= N; ++i)
        fout << lg[i] << ' ' << bs[i] << '\n';

    fin.close();
    fout.close();
    return 0;
}