Pagini recente » Statistici Alex Cristian (bishopp) | Cod sursa (job #54776) | Cod sursa (job #1763666) | Istoria paginii problema/civilizatie | Cod sursa (job #32052)
Cod sursa(job #32052)
#include <cstdio>
#include <algorithm>
#include <utility>
using namespace std;
const int NMAX = 256;
const int MMAX = 256;
const int INF = 0x3f3f3f3f;
int N, M, pot[NMAX+MMAX], cst[NMAX][MMAX];
int matchA[NMAX], matchB[MMAX];
int augment(int source) {
bool used[NMAX+MMAX];
memset(used, 0, sizeof(used));
int dst[NMAX+MMAX];
memset(dst, 0x3f, sizeof(dst));
dst[source] = 0;
int last[NMAX+MMAX];
memset(last, -1, sizeof(last));
for (int step = 0; step < N+M; ++step) {
int minDst = INF, pos = -1;
for (int i = 0; i < N+M; ++i) {
if (!used[i] && minDst > dst[i]) {
minDst = dst[pos = i];
}
}
if (pos == -1) break;
used[pos] = true;
if (pos < N) { // forward edges
for (int i = 0; i < M; ++i) {
if (used[N+i] || cst[pos][i] == INF) continue;
int ndst = dst[pos] + cst[pos][i] + pot[pos] - pot[N+i];
if (ndst < dst[N+i]) {
dst[N+i] = ndst;
last[N+i] = pos;
}
}
} else { // backwards edge
int next = matchB[pos-N];
if (next == -1 || used[next]) continue;
int ndst = dst[pos] - cst[next][pos-N] + pot[pos] - pot[next];
if (ndst < dst[next]) {
dst[next] = ndst;
last[next] = pos;
}
}
}
for (int i = 0; i < N+M; ++i)
if (dst[i] < INF) pot[i] += dst[i];
int minDst = INF, where = -1;
for (int i = 0; i < M; ++i) {
if (matchB[i] == -1 && minDst > dst[N+i]) {
minDst = dst[where = N+i];
}
}
int minCst = 0;
while (where != -1) {
int next = last[where];
if (where >= N) { // match
matchA[next] = where-N;
matchB[where-N] = next;
minCst += cst[next][where-N];
} else {
if (next != -1) minCst -= cst[where][next-N];
}
where = next;
}
return minCst;
}
pair<int, int> minCostBipartiteMatch() {
memset(pot, 0, sizeof(pot));
memset(matchA, -1, sizeof(matchA));
memset(matchB, -1, sizeof(matchB));
int num = 0, cost = 0;
for (int i = 0; i < N; ++i) {
int mcost = augment(i);
if (mcost < INF) {
cost += mcost;
num++;
}
}
return make_pair(num, cost);
}
int main() {
freopen("cc.in", "rt", stdin);
freopen("cc.out", "wt", stdout);
scanf("%d", &N);
M = N;
for (int i = 0; i < N; ++i)
for (int j = 0; j < M; ++j)
scanf("%d", &cst[i][j]);
printf("%d\n", minCostBipartiteMatch().second);
return 0;
}