Cod sursa(job #3194125)

Utilizator anamaria29sSuditu Ana-Maria anamaria29s Data 17 ianuarie 2024 02:00:28
Problema Cc Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.29 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <climits>

using namespace std;

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

vector<vector<int>> adjacencyList, capacity, flowMatrix, distanceMatrix;
vector<int> previousNode, minDistance;
int totalDistance, N, source, dest, distanceValue;

// Funcție pentru parcurgerea grafului cu BFS pentru a găsi un drum de la sursă la destinație
int BFS() {
    fill(previousNode.begin(), previousNode.end(), -1);
    fill(minDistance.begin(), minDistance.end(), INT_MAX);

    minDistance[source] = 0;
    queue<pair<int, int>> q;
    q.push({source, INT_MAX});

    while (!q.empty()) {
        int currentNode = q.front().first;
        int minFlowUntilNow = q.front().second;
        q.pop();

        for (auto& nextNode : adjacencyList[currentNode]) {
            if (minDistance[nextNode] > minDistance[currentNode] + distanceMatrix[currentNode][nextNode] &&
                capacity[currentNode][nextNode] > flowMatrix[currentNode][nextNode]) {

                previousNode[nextNode] = currentNode;
                int residualCapacity = capacity[currentNode][nextNode] - flowMatrix[currentNode][nextNode];
                int nextMinFlow = min(residualCapacity, minFlowUntilNow);
                minDistance[nextNode] = minDistance[currentNode] + distanceMatrix[currentNode][nextNode];

                q.push({nextNode, nextMinFlow});
            }
        }
    }

    return previousNode[dest] >= 0;
}

// Funcție pentru algoritmul lui Edmonds-Karp pentru a găsi fluxul maxim într-un graf
void flux()
{
    while (true) {
        int flowOnPath = BFS();

        if (!flowOnPath) break; // Dacă nu a fost găsit niciun drum augmentat (de la sursă la destinație)

        // În cazul în care a fost găsit, refacem drumul și actualizăm fluxul pe tot drumul
        int currentNode = dest;
        while (currentNode != source) {
            int previous = previousNode[currentNode];
            flowMatrix[previous][currentNode] += flowOnPath;
            flowMatrix[currentNode][previous] -= flowOnPath;
            currentNode = previous;
        }

        totalDistance += minDistance[dest];
    }
    g << totalDistance;
}

int main()
{
    f >> N;
    dest = 2 * N + 1;
    previousNode.resize(dest + 1);
    minDistance.resize(dest + 1);
    adjacencyList.resize(dest + 1, {});
    capacity.assign(dest + 1, vector<int>(dest + 1, 0));
    flowMatrix.resize(dest + 1, vector<int>(dest + 1, 0));
    distanceMatrix.resize(dest + 1, vector<int>(dest + 1, 0));

    // Construirea grafului
    for (int i = 1; i <= N; i++) {
        adjacencyList[0].push_back(i);
        adjacencyList[i].push_back(0);
        capacity[0][i] = 1;

        for (int j = 1; j <= N; j++) {
            f >> distanceValue;
            adjacencyList[i].push_back(j + N);
            adjacencyList[j + N].push_back(i);
            capacity[i][j + N] = 1;
            distanceMatrix[i][j + N] = distanceValue;
            distanceMatrix[j + N][i] = -distanceValue;
        }
    }

    for (int i = 1; i <= N; i++) {
        adjacencyList[i + N].push_back(dest);
        adjacencyList[dest].push_back(i + N);
        capacity[i + N][dest] = 1;
    }

    flux();



    return 0;
}