Cod sursa(job #3189928)

Utilizator bestman4111Tiberiu Niculae bestman4111 Data 6 ianuarie 2024 17:54:13
Problema Cc Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.73 kb
#include<fstream>
#include<vector>
#include<queue>
using namespace std;

#define INF 999999
#define NMAX 201

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

int source, target; // nod sursa, nod destinatie
int adi[NMAX][NMAX]; // matrice de adiacenta
int g[NMAX][NMAX]; // matricea grafului ponderat
int capacity[NMAX][NMAX]; // matrice de capacitate
int flow[NMAX][NMAX]; // matrice de flux
int viz[NMAX]; // vector de vizite
int minCapacity[NMAX]; // vector pentru capacitatea minima
int parinte[NMAX]; // vector de parinti
queue<int> q;

int BellmanFord(){
    // initializare de vectori
    for(int i = source; i <= target; ++i){
        viz[i] = parinte[i] = 0;
        minCapacity[i] = INF;
    }

    viz[source] = 1;
    minCapacity[source] = 0;
    q.push(source);

    while(!q.empty()){
        int k = q.front();
        for(int i = 1; i <= target; ++i){
            if(adi[k][i] && flow[k][i] < capacity[k][i] && minCapacity[k] + g[k][i] < minCapacity[i]){
                minCapacity[i] = minCapacity[k] + g[k][i];
                parinte[i] = k;
                if(!viz[i]){
                    q.push(i);
                    viz[i] = 1;
                }
            }
        }
        viz[k] = 0;
        q.pop();
    }

    // daca exista drum intre source si target
    if(minCapacity[target] != INF){
        int residual = INF;
        int k = target;

        // caut capacitatea reziduala minima a drumului mai bun
        while(k != source){
            residual = min(residual, capacity[parinte[k]][k] - flow[parinte[k]][k]);
            k = parinte[k];
        }

        k = target;

        // actualizez fluxul pe drumul mai bun
        while(k != source){
            flow[k][parinte[k]] -= residual;
            flow[parinte[k]][k] += residual;
            k = parinte[k];
        }

        // returnez fluxul pe acest drum
        return minCapacity[target] * residual;
    }

    return 0;
}

int main()
{
    int N;
    fin >> N;
    for(int i = 1; i <= N; ++i){
        for(int j = 1; j <= N; ++j){
            fin >> g[i][j + N];
            g[j + N][i] = -g[i][j + N];
            adi[i][j + N] = 1;
            adi[j + N][i] = 1;
            capacity[i][j + N] = 1;
        }
    }

    source = 0;
    target = 2 * N + 1;
    for(int i = 1; i <= N; ++i){
        adi[source][i] = 1;
        adi[i][source] = 1;
        capacity[source][i] = 1;
        adi[i + N][target] = 1;
        adi[target][i + N] = 1;
        capacity[i + N][target] = 1;
    }

    int x = 1; // fluxul pentru fiecare drum mai bun
    int rez = 0; // rezultatul

    while(x){
        x = BellmanFord();
        rez += x;
    }

    fout << rez;

    return 0;
}