Pagini recente » Cod sursa (job #2130289) | Cod sursa (job #979042) | Cod sursa (job #631487) | Cod sursa (job #481774) | Cod sursa (job #3190666)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <map>
using namespace std;
ifstream fin("cc.in");
ofstream fout("cc.out");
// Matricea pentru costurile muchiilor și vectorul pentru reprezentarea grafului
int costs[202][202];
class Graph {
vector<vector<int>> edges;
map<pair<int, int>, int> edgeValues; // Mapează perechile de noduri la costurile muchiilor
int numNodes;
public:
Graph(int n = 1) : numNodes(n) {
edges = vector<vector<int>>(n + 1);
}
// Adaugă o muchie între nodurile x și y, cu un cost opțional
void addEdge(int x, int y, int cost = 0) {
edges[x].push_back(y);
edgeValues[{x, y}] = cost;
}
// Setează valoarea unei muchii
void setEdgeValue(int x, int y, int newValue) {
edgeValues[{x, y}] = newValue;
}
// Obține valoarea unei muchii
int getEdgeValue(int x, int y) {
return edgeValues[{x, y}];
}
// Algoritmul BFS pentru aflarea fluxului maxim
void maxFlowBFS(vector<int> &parents, int start, int sink) {
queue<pair<int, int>> q;
q.push({start, INT_MAX});
vector<int> minCost(numNodes, INT_MAX), inQueue(numNodes, 0);
parents[start] = start;
minCost[start] = 0;
while (!q.empty()) {
int currentNode = q.front().first, maxFlow = q.front().second;
inQueue[currentNode] = 0;
for (auto &neighbor : edges[currentNode]) {
if (edgeValues[{currentNode, neighbor}] > 0 && minCost[neighbor] > minCost[currentNode] + costs[currentNode][neighbor]) {
minCost[neighbor] = minCost[currentNode] + costs[currentNode][neighbor];
parents[neighbor] = currentNode;
if (!inQueue[neighbor]) {
inQueue[neighbor] = 1;
q.push({neighbor, min(edgeValues[{currentNode, neighbor}], maxFlow)});
}
}
}
q.pop();
}
}
// Algoritmul principal pentru calculul fluxului maxim
void maxFlow(int n) {
int result = 0;
vector<int> parents(202, -1);
parents[201] = 201;
while (parents[201] != -1) {
parents.assign(202, -1);
maxFlowBFS(parents, 0, 201);
if (parents[201] != -1) {
int currentNode = 201;
while (currentNode != 0) {
edgeValues[{parents[currentNode], currentNode}] -= 1;
edgeValues[{currentNode, parents[currentNode]}] += 1;
currentNode = parents[currentNode];
}
}
}
// Calculul și afișarea rezultatului final
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (edgeValues[{100 + j, i}] > 0) {
result += costs[i][100 + j];
}
}
}
fout << result << '\n';
}
};
int main() {
int n;
fin >> n;
Graph g(202);
// Construirea grafului cu muchii și costuri
for (int i = 1; i <= n; i++) {
g.addEdge(0, i, 1);
g.addEdge(i, 0, 0);
g.addEdge(100 + i, 201, 1);
g.addEdge(201, 100 + i, 0);
for (int j = 1; j <= n; j++) {
fin >> costs[i][100 + j];
costs[100 + j][i] -= costs[i][100 + j];
g.addEdge(i, 100 + j, 1);
g.addEdge(100 + j, i, 0);
}
}
// Apelarea algoritmului pentru calculul fluxului maxim
g.maxFlow(n);
return 0;
}