Pagini recente » Cod sursa (job #2745212) | Cod sursa (job #2971964) | Cod sursa (job #2772537) | Cod sursa (job #309200) | Cod sursa (job #3188379)
#include <fstream>
#include <climits>
#include <vector>
#include <queue>
using namespace std;
ifstream inputFile("cc.in"); // Deschiderea fișierului de intrare
ofstream outputFile("cc.out"); // Deschiderea fișierului de ieșire
// Structura pentru a reprezenta o muchie în graf
struct Edge {
int destination, flow, capacity, cost, reverseEdgeIndex;
};
vector<vector<Edge>> graph; // Graful reprezentat ca un vector de vectori de Edge
// Funcție pentru adăugarea unei muchii în graf
void addEdge(int from, int to, int capacity, int cost) {
graph[from].push_back({to, 0, capacity, cost, static_cast<int>(graph[to].size())});
graph[to].push_back({from, 0, 0, -cost, static_cast<int>(graph[from].size()) - 1});
}
// Funcția principală pentru calculul fluxului minim cu cost minim
int minCostFlow(int source, int sink) {
int totalCost = 0;
while (true) {
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> minHeap;
vector<int> distance(graph.size(), INT_MAX);
vector<pair<int, int>> parent(graph.size());
distance[source] = 0;
minHeap.push({0, source});
while (!minHeap.empty()) {
int currentDistance = minHeap.top().first;
int currentNode = minHeap.top().second;
minHeap.pop();
if (currentDistance > distance[currentNode])
continue;
for (size_t i = 0; i < graph[currentNode].size(); ++i) {
int capacity = graph[currentNode][i].capacity;
int flow = graph[currentNode][i].flow;
int cost = graph[currentNode][i].cost;
int neighbor = graph[currentNode][i].destination;
if (capacity - flow > 0 && distance[currentNode] < INT_MAX && distance[neighbor] > distance[currentNode] + cost) {
distance[neighbor] = distance[currentNode] + cost;
minHeap.push({distance[neighbor], neighbor});
parent[neighbor] = {currentNode, static_cast<int>(i)};
}
}
}
if (distance[sink] == INT_MAX)
break;
int bottleneck = INT_MAX;
for (int current = sink; current != source; current = parent[current].first) {
int previous = parent[current].first;
int edgeIndex = parent[current].second;
bottleneck = min(bottleneck, graph[previous][edgeIndex].capacity - graph[previous][edgeIndex].flow);
}
for (int current = sink; current != source; current = parent[current].first) {
int previous = parent[current].first;
int edgeIndex = parent[current].second;
graph[previous][edgeIndex].flow += bottleneck;
graph[current][graph[previous][edgeIndex].reverseEdgeIndex].flow -= bottleneck;
totalCost += bottleneck * graph[previous][edgeIndex].cost;
}
}
return totalCost;
}
int main() {
int n;
inputFile >> n;
graph.resize(2 * n + 2);
int source = 2 * n, sink = 2 * n + 1;
for (int i = 0; i < n; ++i) {
addEdge(source, i, 1, 0);
addEdge(i + n, sink, 1, 0);
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
int edgeCost;
inputFile >> edgeCost;
addEdge(i, j + n, 1, edgeCost);
}
}
outputFile << minCostFlow(source, sink);
inputFile.close(); // Închiderea fișierului de intrare
outputFile.close(); // Închiderea fișierului de ieșire
return 0;
}