Pagini recente » Cod sursa (job #211698) | Cod sursa (job #3126454) | Cod sursa (job #3175384) | Cod sursa (job #2567301) | Cod sursa (job #2333755)
#include <bits/stdc++.h>
#define maxN 102
#define inf 0x3fffffff
using namespace std;
FILE *fin = freopen("cc.in", "r", stdin);
FILE *fout = freopen("cc.out", "w", stdout);
int N;
int c[maxN][maxN], cost[maxN][maxN];
int Pair[2 * maxN];
bool vis[2 * maxN], mvc[2 * maxN];
int ans;
bool Pairup(int x)
{
if (vis[x])
return 0;
vis[x] = 1;
for (int y = 0; y < N; ++ y)
if (c[x][y] == 0)
if (Pair[y + N] == -1 || Pairup(Pair[y + N]))
{
Pair[x] = y + N;
Pair[y + N] = x;
return 1;
}
return 0;
}
int maxMatching()
{
bool ok = false;
ans = 0;
memset(Pair, -1, sizeof(Pair));
do
{
ok = false;
memset(vis, 0, sizeof(vis));
for (int i = 0; i < N; ++ i)
if (Pair[i] == -1)
ok |= Pairup(i);
}
while (ok);
int ret = 0;
for (int i = 0; i < N; ++ i) if (Pair[i] != -1)
{
ans += cost[i][Pair[i] - N];
++ ret;
}
return ret;
}
/// try to use thins approach for normal graphs?
void comp0WeightEdges()
{
for (int i = 0; i < N; ++ i)
{
int minc = inf;
for (int j = 0; j < N; ++ j)
minc = min(minc, c[i][j]);
for (int j = 0; j < N; ++ j)
c[i][j] -= minc;
//ans += minc;
}
}
void compMVC(int u)
{
for (int v = 0; v < N; ++ v)
if (c[u][v] == 0 && !mvc[v + N])
{
mvc[v + N] = true;
mvc[Pair[v + N]] = false;
compMVC(Pair[v + N]);
}
}
int minEdgeMVC()
{
int delta = inf;
for (int i = 0; i < N; ++ i)
if (!mvc[i])
for (int j = 0; j < N; ++ j) if (!mvc[j + N])
delta = min(delta, c[i][j]);
return delta;
}
void recompC(int delta)
{
for (int i = 0; i < N; ++ i)
for (int j = 0; j < N; ++ j)
if (!mvc[i] && !mvc[j + N])
c[i][j] -= delta;
else if (mvc[i] && mvc[j + N])
c[i][j] += delta;
}
int main()
{
scanf("%d", &N);
for (int i = 0; i < N; ++ i)
for (int j = 0; j < N; ++ j)
{
scanf("%d", &c[i][j]);
cost[i][j] = c[i][j];
}
comp0WeightEdges();
int prvD = 0;
while(1)
{
int sz = maxMatching();
if (sz == N)
break;
memset(mvc, false, sizeof(mvc));
for (int i = 0; i < N; ++ i)
if (Pair[i] != -1)
mvc[i] = true;
for (int i = 0; i < N; ++ i)
if (Pair[i] == -1)
compMVC(i);
int delta = minEdgeMVC();
recompC(delta);
}
printf("%d\n", ans);
return 0;
}