Cod sursa(job #3190439)

Utilizator tudormiuMiu Tudor Gabriel tudormiu Data 7 ianuarie 2024 16:43:00
Problema Cc Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.67 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

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

const int N_MAX = 205;
const int INF = 2e9;

class MaxFlow {
public:
    MaxFlow(ifstream& fin, ofstream& fout);
    void readInput();
    void initializeGraph();
    int Bellman_Ford();
    void findMaxFlow();
    void printResult();

private:
    int n, m, s, d;
    vector<pair<int, int>> v[N_MAX];
    int t[N_MAX];
    int dist[N_MAX];
    int flux[N_MAX][N_MAX];
    bool viz[N_MAX];
    ofstream& fout;
};

MaxFlow::MaxFlow(ifstream& fin, ofstream& fout) : fout(fout) {
    readInput();
    initializeGraph();
}

void MaxFlow::readInput() {
    fin >> n;
    m = n;
}

void MaxFlow::initializeGraph() {
    s = 0;
    d = 2 * n + 1;

    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            int cost;
            fin >> cost;
            v[i].push_back(make_pair(j + n, cost));
            v[j + n].push_back(make_pair(i, -cost));
            flux[i][j + n] = 1;
        }
    }

    for (int i = 1; i <= n; i++) {
        v[0].push_back(make_pair(i, 0));
        v[i].push_back(make_pair(0, 0));
        v[2 * n + 1].push_back(make_pair(i + n, 0));
        v[i + n].push_back(make_pair(2 * n + 1, 0));
        flux[0][i] = 1;
        flux[i + n][2 * n + 1] = 1;
    }
}

int MaxFlow::Bellman_Ford() {
    int i;
    for (i = 0; i <= 2 * n + 1; i++) {
        viz[i] = false;
        dist[i] = INF;
    }

    queue<int> q;
    q.push(s);
    dist[s] = 0;
    viz[s] = true;

    while (!q.empty()) {
        int p = q.front();
        q.pop();
        viz[p] = false;

        for (auto i : v[p]) {
            if (flux[p][i.first] > 0 && dist[i.first] > dist[p] + i.second) {
                dist[i.first] = dist[p] + i.second;

                if (!viz[i.first]) {
                    q.push(i.first);
                    viz[i.first] = true;
                }

                t[i.first] = p;
            }
        }
    }

    return dist[d];
}

void MaxFlow::findMaxFlow() {
    int maxi = 0;
    while (true) {
        int mini = INF;
        int suma = Bellman_Ford();

        if (suma == INF)
            break;

        int x = d;
        while (x != s) {
            mini = min(mini, flux[t[x]][x]);
            x = t[x];
        }

        x = d;
        while (x != s) {
            flux[x][t[x]] += mini;
            flux[t[x]][x] -= mini;
            x = t[x];
        }

        maxi += mini * suma;
    }

    fout << maxi;
}

void MaxFlow::printResult() {
    fout << endl;
}

int main() {

    MaxFlow maxFlowMinCost(fin, fout);
    maxFlowMinCost.findMaxFlow();
    maxFlowMinCost.printResult();

    return 0;
}