Cod sursa(job #3039158)

Utilizator vladth11Vlad Haivas vladth11 Data 28 martie 2023 11:18:40
Problema Coduri Huffman Scor 65
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.93 kb
#include <bits/stdc++.h>
#define debug(x) cerr << #x << " " << x << "\n"
#define debugs(x) cerr << #x << " " << x << " "
#pragma GCC optimize("Ofast")

using namespace std;
typedef long long ll;
typedef pair <ll, ll> pii;

const ll NMAX = 2000001;
const ll INF = 1e9;
const ll nrbits = 17;
const ll MOD = 998244353;

vector <pii> g[NMAX];
ll sum;

pii operator + (pii a, pii b) {
    return {a.first + b.first, a.second + b.second};
}

void minSelf(pii &a, pii b) {
    a = min(a, b);
}

ll f[NMAX];
pii sol[NMAX];

void addEdge(ll a, ll b, ll c) {
    g[a].push_back({b, c});
}

void DFS(ll node, ll lvl, ll nr) {
    if(g[node].size() == 0) {
        sum += (ll)f[node] * lvl;
        sol[node] = {lvl, nr};
    }
    for(auto x : g[node]) {
        DFS(x.first, lvl + 1, nr * 2 + x.second);
    }
}


queue <pii> v;
queue <pii> q;

pii getmin() {
    pii minim = {2e9, 0};
    if(v.size()) {
        minSelf(minim, v.front());
    }
    if(q.size()) {
        minSelf(minim, q.front());
    }
    return minim;
}

int main() {
//#ifdef HOME
    ifstream cin("huffman.in");
    ofstream cout("huffman.out");
//#endif // HOME
    ll n, i, ini = 0;
    cin >> n;
    for(i = 1; i <= n; i++) {
        cin >> f[i];
        v.push({f[i], i});
    }
    ini = n;
    while(v.size() + q.size() > 1) {
        pii minim = {2e9, 0};
        n++;
        pii x = getmin();
        if(x == v.front()) {
            v.pop();
        } else {
            q.pop();
        }
        pii y = getmin();
        if(y == v.front())
            v.pop();
        else
            q.pop();
        addEdge(n, y.second, 1);
        addEdge(n, x.second, 0);
        minim = (x + y);
        q.push({minim.first, n});
    }
    /// Caz special pt n == 1
    DFS(n, 0, 0);
    cout << sum << "\n";
    for(i = 1; i <= ini; i++) {
        cout << sol[i].first << " " << sol[i].second << "\n";
    }
}