Cod sursa(job #3191965)

Utilizator az234as arf az234 Data 11 ianuarie 2024 04:28:07
Problema Cc Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.38 kb
#include <fstream>
#include <vector>
#include <deque>
#include <queue>
using namespace std;
ifstream fin("cc.in");
ofstream fout("cc.out");
const int N = 205;
const int INF = 1e9;
int n, cost, nodStart, nodFinal,distanta[N],costuri[N][N];
int flux[N][N], parinte[N];
bool vizitat[N];
vector<int> graf[N];
//  Bellman-Ford pentru  drumurile de creștere
int bellmanFord(int nodStart, int nodFinal) {
    for (int i = nodStart; i <= nodFinal; ++i) {
        parinte[i] = 0;
        vizitat[i] = false;
        distanta[i] = INF;
    }
    distanta[nodStart] = 0;
    vizitat[nodStart] = true;
    queue<int> q;
    q.push(nodStart);
    while (!q.empty()) {
        int nod = q.front();
        q.pop();
        vizitat[nod] = false;
        for (auto vecin : graf[nod]) {
            if (flux[nod][vecin] > 0 && distanta[vecin] > distanta[nod] + costuri[nod][vecin]) {
                distanta[vecin] = distanta[nod] + costuri[nod][vecin];
                parinte[vecin] = nod;
                if (!vizitat[vecin]) {
                    vizitat[vecin] = true;
                    q.push(vecin);
                }
            }
        }
    }

    return distanta[nodFinal];
}

int main() {
    fin >> n;

    // construire graf
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            fin >> cost;
            costuri[i][j + n] = cost;
            costuri[j + n][i] = -cost;
            flux[i][j + n] = 1;
            graf[i].push_back(j + n);
            graf[j + n].push_back(i);
        }
    }

    // nod de start fictiv 0
    // nod final fictiv 2n+1
    for (int i = 1; i <= n; ++i) {
        graf[0].push_back(i);
        graf[i].push_back(0);
        graf[2 * n + 1].push_back(i + n);
        graf[i + n].push_back(2 * n + 1);
        flux[0][i] = 1;
        flux[i + n][2 * n + 1] = 1;
    }

    nodStart = 0;
    nodFinal = 2 * n + 1;
    int rezultat = 0;

    while (true) {
        int suma = bellmanFord(nodStart, nodFinal);
        if (suma == INF)
            break;

        int fluxMinim = INF;

        for (int i = nodFinal; i != nodStart; i = parinte[i])
            fluxMinim = min(fluxMinim, flux[parinte[i]][i]);

        for (int i = nodFinal; i != nodStart; i = parinte[i]) {
            flux[parinte[i]][i] -= fluxMinim;
            flux[i][parinte[i]] += fluxMinim;
        }

        rezultat = rezultat + suma * fluxMinim;
    }

    fout << rezultat;

    return 0;
}