Cod sursa(job #3039186)

Utilizator vladth11Vlad Haivas vladth11 Data 28 martie 2023 11:52:49
Problema Coduri Huffman Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.12 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 <int, int> pii;

const ll NMAX = 1000001;
const ll INF = (1LL << 60);
const ll nrbits = 17;
const ll MOD = 998244353;

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

 pair <ll, int> operator + ( pair <ll, int> a,  pair <ll, int> b) {
    return {a.first + b.first, a.second + b.second};
}

void minSelf( pair <ll, int> &a,  pair <ll, int> b) {
    a = min(a, b);
}

int f[NMAX];
pair <int, ll> sol[NMAX];

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

void DFS(int node, int 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 <pair <ll, int> > v;
queue <pair <ll, int> > q;

 pair <ll, int> getmin() {
     pair <ll, int> minim = {INF, 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
    int 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) {
         pair <ll, int> minim = {INF, 0};
        n++;
        pair <ll, int> x = getmin();
        if(v.size() && x == v.front()) {
            v.pop();
        } else {
            q.pop();
        }
         pair <ll, int> y = getmin();
        if(v.size() && 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";
    }
}