Cod sursa(job #3190727)

Utilizator AnaRosuAna Maria Rosu AnaRosu Data 7 ianuarie 2024 21:00:42
Problema Cc Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.05 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <fstream>
using namespace std;

ifstream f("cc.in");
ofstream g("cc.out");

const int MAX_N = 203;
int n, capac[MAX_N][MAX_N], flux[MAX_N][MAX_N], s = 0, t, c;
char pct;
vector<int> graf[MAX_N];
queue<int> coada;
vector<int> tati(MAX_N, -1);
vector<vector<int>> cost(MAX_N, vector<int>());
const int oo = 1e9;

void constr_graf() {
    for (int elev = 1; elev <= n; elev++) {
        graf[s].push_back(elev);
        graf[elev].push_back(s);
        capac[s][elev] = 1;

        for (int calculator = n + 1; calculator <= 2 * n; calculator++) {
            f >> c;
            graf[elev].push_back(calculator + n);
            graf[calculator + n].push_back(elev);

            cost[elev][calculator] = c;
            cost[calculator][elev] = -c;

            capac[elev][calculator + n] = 1;
        }
    }
    for (int calculator = n + 1; calculator <= 2 * n; calculator++) {
        graf[calculator].push_back(t);
        graf[t].push_back(calculator);
        capac[calculator][t] = 1;
    }
    f.close();
}

bool constr_drum_crestere(queue<int>& coada, vector<int>& tati, vector<vector<int>>& cost) {
    vector <int> cost_temp(t, oo);
    coada.push(s);
    cost_temp[s] = 0;
    while (!coada.empty()) {
        int nod = coada.front();
        coada.pop();
        for (int vecin : graf[nod]) {
            // unsaturated path and better cost
            if (cost_temp[nod] + cost[nod][vecin] < cost_temp[vecin] && capac[nod][vecin] - flux[nod][vecin] > 0) {
                coada.push(vecin);
                tati[vecin] = nod;
                cost_temp[vecin] = cost_temp[nod] + cost[nod][vecin];

                if (vecin == t)
                    return true;
            }
        }
    }
    return false;
}

void reviz_drum(queue<int>& coada, vector<int>& tati, vector<vector<int>>& cost) {
    int fmax = oo;
    int nod = t;
    while (nod != s) {
        int prev = tati[nod];
        fmax = min(capac[prev][nod] - flux[prev][nod], fmax);
        nod = prev;
    }
    // cresc fluxul pe fiecare arc direct din drumul de crestere 
    // scad fluxul pe fiecare arc invers din drumul de crestere
    nod = t;
    while (nod != s) {
        int prev = tati[nod];

        flux[prev][nod] += fmax;
        flux[nod][prev] -= fmax;

        nod = prev;
    }
}

void edmondsKarp() {
    
    while (constr_drum_crestere(coada, tati, cost)) {
        reviz_drum(coada, tati, cost);
        coada = queue<int>();
        tati = vector<int>(MAX_N, -1);
        cost = vector<vector<int>>(MAX_N, vector<int>());
    }
}



int main() {
    f >> n; 
    t = 2*n + 1;

    constr_graf();
    edmondsKarp();
    int sol = 0;
    for(int elev = 1; elev <= n; elev++)
        for(int calc = n + 1; calc <= 2 * n; calc++)
            if(flux[elev][calc])
            {
                sol += cost[elev][calc];
                continue;
            }

    g << sol;
    g.close();
    return 0;
}