Pagini recente » Cod sursa (job #3237063) | Cod sursa (job #3164610) | Cod sursa (job #3263865) | Cod sursa (job #3263097) | Cod sursa (job #3194125)
#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;
}