Pagini recente » Cod sursa (job #1200728) | Cod sursa (job #1854217) | Cod sursa (job #259020) | Cod sursa (job #2357169) | Cod sursa (job #141641)
Cod sursa(job #141641)
#include <stdio.h>
#include <values.h>
#define nmax 222
int N, ans;
int cst[nmax][nmax], cap[nmax][nmax];
int cat[nmax], uni[nmax], viz[nmax];
int nod[nmax*nmax];
void read()
{
int i, j;
freopen("cc.in", "r", stdin);
scanf("%d", &N);
for (i = 1; i <= N; ++i)
for (j = 1; j <= N; ++j)
scanf("%d", &cst[i][j+N]);
}
int dfs()
{
int i, j, ic, sc, suma, flux;
cat[uni[0] = nod[ic = sc = 0] = suma = 0] = MAXINT/2;
for (i = 1; i <= N+N+1; ++i)
uni[i] = cat[i] = viz[i] = MAXINT/2;
viz[0] = -1;
while (ic <= sc)
{
i = nod[ic++];
for (j = 0; j <= N+N+1; j++)
if (cap[i][j] > 0 && uni[i] + cst[i][j] < uni[j])
{
nod[++sc] = j;
viz[j] = i;
uni[j] = uni[i] + cst[i][j];
cat[j] = cat[i] < cap[i][j]? cat[i]: cap[i][j];
}
}
if (viz[N+N+1] == MAXINT/2)
return 1;
for (j = N+N+1, flux = cat[N+N+1]; viz[j] != -1; j = viz[j])
{
i = viz[j];
cap[i][j] -= flux;
cap[j][i] += flux;
}
for (i = N+1; i <= N+N; ++i)
suma += cap[N+N+1][i];
if (suma < N)
return 1;
return 0;
}
void solve()
{
int i, j;
// nodul 0 = sursa
for (i = 1; i <= N; ++i)
cap[0][i] = 1;
// nodul 2N+1 = destinatia
for (i = N+1; i <= N+N; ++i)
cap[i][N+N+1] = 1;
// intre nodurile din 1..N si N+1..2N
for (i = 1; i <= N; ++i)
for (j = N+1; j <= N+N; ++j)
{
cap[i][j] = 1;
cst[j][i] = -cst[i][j];
}
while (dfs());
// calculez costurile, ca fiind costurile realizate intre i si j
for (i = 1; i <= N; ++i)
for (j = N+1; j <= N+N; ++j)
ans += cst[i][j] * cap[j][i];
}
void write()
{
freopen("cc.out", "w", stdout);
printf("%d\n", ans);
}
int main()
{
read();
solve();
write();
return 0;
}