Pagini recente » Cod sursa (job #719391) | Cod sursa (job #2635011) | Cod sursa (job #352378) | Cod sursa (job #2121190) | Cod sursa (job #2588606)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("cc.in");
ofstream fout("cc.out");
class FlowNetwork {
private:
int n, s, t;
vector<vector<int>> ad, cap, cst;
vector<int> pot, dst;
void bellman() {
fill(pot.begin(), pot.end(), 1e9);
pot[s] = 0;
vector<bool> inQueue(n + 1);
inQueue[s] = true;
queue<int> q; q.push(s);
while (!q.empty()) {
int node = q.front(); q.pop();
inQueue[node] = false;
for (int nghb : ad[node])
if (cap[node][nghb] && pot[node] + cst[node][nghb] < pot[nghb]) {
pot[nghb] = pot[node] + cst[node][nghb];
if (!inQueue[nghb]) {
q.push(nghb);
inQueue[nghb] = true;
}
}
}
}
bool dijkstra(vector<int>& dp, vector<int>& father) {
fill(dp.begin(), dp.end(), 1e9);
dp[s] = dst[s] = 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.emplace(0, s);
vector<bool> vis(n + 1);
while (!pq.empty()) {
int node = pq.top().second; pq.pop();
if (node != t && !vis[node]) {
vis[node] = true;
for (int nghb : ad[node])
if (cap[node][nghb] && dp[node] + cst[node][nghb] + pot[node] - pot[nghb] < dp[nghb]) {
dp[nghb] = dp[node] + cst[node][nghb] + pot[node] - pot[nghb];
father[nghb] = node;
dst[nghb] = dst[node] + cst[node][nghb];
pq.emplace(dp[nghb], nghb);
}
}
}
pot = dst;
return dp[t] != 1e9;
}
public:
FlowNetwork(int n, int s, int t) :
n(n), s(s), t(t), ad(n + 1),
cap(n + 1, vector<int>(n + 1)),
cst(n + 1, vector<int>(n + 1)),
pot(n + 1), dst(n + 1) { }
void addEdge(int x, int y, int z, int t) {
ad[x].push_back(y);
ad[y].push_back(x);
cap[x][y] = z;
cst[x][y] = +t;
cst[y][x] = -t;
}
int matching() {
int cost = 0;
vector<int> dp(n + 1);
vector<int> father(n + 1);
bellman();
while (dijkstra(dp, father)) {
int flow = 1e9;
for (int i = t; i != s; i = father[i])
flow = min(flow, cap[father[i]][i]);
for (int i = t; i != s; i = father[i]) {
cost += flow * cst[father[i]][i];
cap[father[i]][i] -= flow;
cap[i][father[i]] += flow;
}
}
return cost;
}
};
int main() {
int n; fin >> n;
FlowNetwork graph(2 * n + 2, 2 * n + 1, 2 * n + 2);
for (int i = 1; i <= n; i++) {
graph.addEdge(2 * n + 1, i, 1, 0);
graph.addEdge(n + i, 2 * n + 2, 1, 0);
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++) {
int x; fin >> x;
graph.addEdge(i, n + j, 1, x);
}
fout << graph.matching() << '\n';
fout.close();
return 0;
}