Cod sursa(job #3191080)

Utilizator PaulaBPaula Balan PaulaB Data 8 ianuarie 2024 19:36:11
Problema Cc Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.99 kb
#include <bits/stdc++.h>
using namespace std;

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

int N, nodDestinatie, dist;
vector<vector<int>> listaAdj, capacitate, flow, matriceDist;
vector<int> nodAnterior, minDist;
int rezultat;

// Funcție pentru parcurgerea în lățime (BFS) pentru găsirea unui drum de la sursă la destinație
int bfs() {
    // Inițializarea nodurilor precedente și a distanței minime pentru fiecare iterație a BFS
    nodAnterior.assign(nodDestinatie + 1, -1);
    minDist.assign(nodDestinatie + 1, INT_MAX);
    minDist[0] = 0;

    queue<pair<int, int>> q;
    q.push({0, INT_MAX});

    while (!q.empty()) {
        int curent = q.front().first, minFlow = q.front().second;
        q.pop();

        // Parcurgerea vecinilor nodului curent în graf
        for (auto &urmator : listaAdj[curent]) {
            // Verificarea dacă există o capacitate nefolosită pe muchia de la nodul curent la nodul vecin
            if (minDist[urmator] > minDist[curent] + matriceDist[curent][urmator] && capacitate[curent][urmator] > flow[curent][urmator]) {
                // Actualizarea nodului vecin și adăugarea la coadă pentru explorare ulterioară
                nodAnterior[urmator] = curent;
                int residualCap = capacitate[curent][urmator] - flow[curent][urmator];
                int urmatorMinFlow = residualCap > minFlow ? minFlow : residualCap;
                minDist[urmator] = minDist[curent] + matriceDist[curent][urmator];
                q.push({urmator, urmatorMinFlow});
            }
        }
    }

    // Returnează true dacă a fost găsit un drum de la sursă la destinație
    return nodAnterior[nodDestinatie] >= 0;
}

// Algoritmul Edmonds-Karp pentru găsirea fluxului maxim și a distanței minime
void edmondsKarpAlgorithm() {
    while (true) {
        int flowOfPath = bfs();

        // Dacă nu mai există drumuri augmentate, se oprește
        if (!flowOfPath) break;

        int curent = nodDestinatie;
        // Refacerea drumului și actualizarea fluxului pe tot traseul
        while (curent != 0) {
            int anterior = nodAnterior[curent];
            flow[anterior][curent] += flowOfPath;
            flow[curent][anterior] -= flowOfPath;
            curent = anterior;
        }

        // Adăugarea la distanța totală
        rezultat += minDist[nodDestinatie];
    }
}

int main() {
    in >> N;
    nodDestinatie = 2 * N + 1;

    // Inițializarea vectorilor și matricelor pentru graful de flux
    nodAnterior.resize(nodDestinatie + 1);
    minDist.resize(nodDestinatie + 1);
    listaAdj.resize(nodDestinatie + 1, {});
    capacitate.assign(nodDestinatie + 1, vector<int>(nodDestinatie + 1, 0));
    flow.resize(nodDestinatie + 1, vector<int>(nodDestinatie + 1, 0));
    matriceDist.resize(nodDestinatie + 1, vector<int>(nodDestinatie + 1, 0));

    // Construirea grafului și a matricelor de capacitate și distanță
    for (int i = 1; i <= N; i++) {
        // Adăugarea muchiilor de la sursă către nodurile concurenților
        listaAdj[0].push_back(i);
        listaAdj[i].push_back(0);
        capacitate[0][i] = 1;

        for (int j = 1; j <= N; j++) {
            in >> dist;
            
            // Adăugarea muchiilor între concurenți și calculatoare și inițializarea matricii de distanțe
            listaAdj[i].push_back(j + N);
            listaAdj[j + N].push_back(i);
            capacitate[i][j + N] = 1;
            matriceDist[i][j + N] = dist;
            matriceDist[j + N][i] = -dist;
        }
    }

    // Adăugarea muchiilor de la calculatoare la nodul destinație
    for (int i = 1; i <= N; i++) {
        listaAdj[i + N].push_back(nodDestinatie);
        listaAdj[nodDestinatie].push_back(i + N);
        capacitate[i + N][nodDestinatie] = 1;
    }

    // Apelarea algoritmului Edmonds-Karp
    edmondsKarpAlgorithm();

    // Scrierea rezultatului în fișierul de ieșire
    out << rezultat;

    return 0;
}