Pagini recente » Cod sursa (job #3264798) | Cod sursa (job #2664632) | Cod sursa (job #3274629) | Cod sursa (job #3285489) | Cod sursa (job #3193926)
#include <iostream>
#include <vector>
#include <queue>
#include <climits>
#include <fstream>
using namespace std;
const int MAX_N = 105;
const int INF = INT_MAX;
struct Edge
{
int to, capacity, cost, flow;
Edge *rev;
};
vector<Edge *> graph[MAX_N * 2];
int N, dist[MAX_N * 2], parent[MAX_N * 2];
Edge *path[MAX_N * 2];
void addEdge(int from, int to, int capacity, int cost)
{
Edge *forward = new Edge{to, capacity, cost, 0, nullptr};
Edge *backward = new Edge{from, 0, -cost, 0, forward};
forward->rev = backward;
graph[from].push_back(forward);
graph[to].push_back(backward);
}
bool spfa(int s, int t)
{
fill(dist, dist + MAX_N * 2, INF);
bool inQueue[MAX_N * 2] = {false};
queue<int> q;
dist[s] = 0;
q.push(s);
inQueue[s] = true;
while (!q.empty())
{
int u = q.front();
q.pop();
inQueue[u] = false;
for (Edge *e : graph[u])
{
if (e->capacity > e->flow && dist[e->to] > dist[u] + e->cost)
{
dist[e->to] = dist[u] + e->cost;
parent[e->to] = u;
path[e->to] = e;
if (!inQueue[e->to])
{
q.push(e->to);
inQueue[e->to] = true;
}
}
}
}
return dist[t] != INF;
}
int minCostMaxFlow(int s, int t)
{
int flow = 0, cost = 0;
while (spfa(s, t))
{
int f = INF;
for (int u = t; u != s; u = parent[u])
{
f = min(f, path[u]->capacity - path[u]->flow);
}
for (int u = t; u != s; u = parent[u])
{
path[u]->flow += f;
path[u]->rev->flow -= f;
cost += path[u]->cost * f;
}
flow += f;
}
return cost;
}
int main()
{
ifstream fin("cc.in");
ofstream fout("cc.out");
fin >> N;
int source = 0, sink = 2 * N + 1;
for (int i = 1; i <= N; ++i)
{
addEdge(source, i, 1, 0);
addEdge(N + i, sink, 1, 0);
}
for (int i = 1; i <= N; ++i)
{
for (int j = 1; j <= N; ++j)
{
int cost;
fin >> cost;
addEdge(i, N + j, 1, cost);
}
}
int minCost = minCostMaxFlow(source, sink);
fout << minCost << endl;
fin.close();
fout.close();
return 0;
}