Pagini recente » Cod sursa (job #2879883) | Cod sursa (job #1447849) | Cod sursa (job #2488024) | Cod sursa (job #1312367) | Cod sursa (job #1435347)
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <limits>
using namespace std;
const int MAX_N = 202;
struct edge {
int cost, cap, v;
};
vector<int> G[MAX_N];
int cap[MAX_N][MAX_N], cost[MAX_N][MAX_N], N;
vector<int> bellman_ford(int source, int dest) {
vector<char> in_queue(2 * N + 2, 0);
vector<int> dist(2 * N + 2, numeric_limits<int>::max() / 2);
vector<int> parent(2 * N + 2, -1);
queue<int> q;
q.push(source); dist[source] = 0; in_queue[source] = 1;
while (!q.empty()) {
int node = q.front();
in_queue[node] = 0;
q.pop();
for (auto v : G[node]) {
if ((dist[v] > dist[node] + cost[node][v]) && cap[node][v] > 0) {
dist[v] = dist[node] + cost[node][v];
parent[v] = node;
if (!in_queue[v]) {
in_queue[v] = 1;
q.push(v);
}
}
}
}
vector<int> path;
for (int node = dest; node != -1; node = parent[node]) {
path.push_back(node);
}
reverse(path.begin(), path.end());
return path;
}
int saturate(const vector<int>& path) {
if (path.size() < 2)
return -1;
int flow = cap[path[0]][path[1]];
int total_cost = cost[path[0]][path[1]];
for (int i = 1; i < path.size() - 1; ++i) {
flow = min(flow, cap[path[i]][path[i + 1]]);
total_cost += cost[path[i]][path[i + 1]];
}
for (int i = 0; i < path.size() - 1; ++i) {
cap[path[i]][path[i + 1]] -= flow;
cap[path[i + 1]][path[i]] += flow;
}
return flow * total_cost;
}
int max_flow() {
int max_flow = 0;
while(1) {
vector<int> path = std::move(bellman_ford(0, 2 * N + 1));
int flow = saturate(path);
if (flow == -1)
return max_flow;
max_flow += flow;
}
}
int main() {
ifstream fin("cc.in");
ofstream fout("cc.out");
fin >> N;
for (int i = 1; i <= N; ++i)
for (int j = 1; j <= N; ++j) {
fin >> cost[i][N + j];
cap[i][N + j] = 1;
cap[N + j][i] = 0;
cost[N + j][i] = -cost[i][N + j];
G[i].push_back(N + j);
G[N + j].push_back(i);
}
for (int i = 1; i <= N; ++i) {
cap[0][i] = 1;
G[0].push_back(i);
G[i].push_back(0);
}
for (int i = N + 1; i <= 2 * N; ++i) {
cap[i][2 * N + 1] = 1;
G[i].push_back(2 * N + 1);
G[2 * N + 1].push_back(i);
}
fout << max_flow() << endl;
fin.close();
fout.close();
}