Cod sursa(job #3189868)

Utilizator mariapreda19Preda Maria mariapreda19 Data 6 ianuarie 2024 16:37:28
Problema Cc Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.24 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <climits>

class Graf {
    int numarNoduri;
    std::vector<std::vector<int>> capacitati;
    std::vector<std::vector<int>> costuri;
    std::vector<std::vector<int>> flux;

public:
    explicit Graf(int numarNoduri) : numarNoduri(numarNoduri) {
        capacitati.resize(numarNoduri);
        costuri.resize(numarNoduri);
        flux.resize(numarNoduri);

        for (int i = 0; i < numarNoduri; i++) {
            capacitati[i].resize(numarNoduri, 0);
            costuri[i].resize(numarNoduri, 0);
            flux[i].resize(numarNoduri, 0);
        }
    }

    void adaugaCapacitate(int x, int y, int capacitate, int cost) {
        capacitati[x][y] = capacitate;
        capacitati[y][x] = 0;
        costuri[x][y] = cost;
        costuri[y][x] = -cost;
    }

    bool bellmanFord(int sursa, int destinatie, std::vector<int>& tati) {
        std::vector<int> distante(numarNoduri, INT_MAX);
        distante[sursa] = 0;

        for (int k = 0; k < numarNoduri - 1; k++) {
            for (int i = 0; i < numarNoduri; i++) {
                for (int j = 0; j < numarNoduri; j++) {
                    if (capacitati[i][j] - flux[i][j] > 0 && distante[i] != INT_MAX &&
                        distante[i] + costuri[i][j] < distante[j]) {
                        distante[j] = distante[i] + costuri[i][j];
                        tati[j] = i;
                    }
                }
            }
        }

        return distante[destinatie] != INT_MAX;
    }

    int fluxMaxim(int sursa, int destinatie) {
        int fluxMaxim = 0;
        std::vector<int> tati(numarNoduri, -1);

        while (bellmanFord(sursa, destinatie, tati)) {
            int fluxMinim = INT_MAX;
            int nod = destinatie;

            while (nod != sursa) {
                fluxMinim = std::min(fluxMinim, capacitati[tati[nod]][nod] - flux[tati[nod]][nod]);
                nod = tati[nod];
            }

            fluxMaxim += fluxMinim;
            nod = destinatie;

            while (nod != sursa) {
                flux[tati[nod]][nod] += fluxMinim;
                flux[nod][tati[nod]] -= fluxMinim;
                nod = tati[nod];
            }
        }

        return fluxMaxim;
    }

    int getCostMinim() const {
        int costMinim = 0;

        for (int i = 0; i < numarNoduri; i++) {
            for (int j = 0; j < numarNoduri; j++) {
                costMinim += flux[i][j] * costuri[i][j];
            }
        }

        return costMinim;
    }
};

int main() {
    std::ifstream fin("cc.in");
    std::ofstream fout("cc.out");

    int N;
    fin >> N;

    Graf g(2 * N + 2);

    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            int distance;
            fin >> distance;
            g.adaugaCapacitate(i, j + N, 1, distance);
        }
    }
    fin.close();

    int sursa = 2 * N;
    int destinatie = 2 * N + 1;

    for (int i = 0; i < N; ++i) {
        g.adaugaCapacitate(sursa, i, 1, 0);
    }

    for (int j = 0; j < N; ++j) {
        g.adaugaCapacitate(j + N, destinatie, 1, 0);
    }

    g.fluxMaxim(sursa, destinatie);

    int minDistanceSum = g.getCostMinim();

    minDistanceSum /= 2;

    fout << minDistanceSum << '\n';

    fout.close();

    return 0;
}