Cod sursa(job #285292)

Utilizator ScrazyRobert Szasz Scrazy Data 22 martie 2009 14:50:38
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.72 kb
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;

#define inf 0x3f3f3f3f

const int maxn = 2 * 102;

int n;
int f[maxn][maxn], c[maxn][maxn], cost[maxn][maxn];
vector<int> g[maxn];

int inq[maxn], d[maxn], p[maxn];

int S, D;

void read()
{
    scanf("%d", &n);
    S = 0; D = 2 * n + 1;
    for (int i = 1; i <= n; ++i)
	for (int j = 1; j <= n; ++j)
	{
	    int x; scanf("%d", &x); 
	    g[i].push_back(j + n);
	    g[j + n].push_back(i);
	    cost[i][j + n] = x;
	    cost[j + n][i] = -x;
	    c[i][j + n] = 1;
	}
    for (int i = 1; i <= n; ++i)
    {
	g[0].push_back(i); g[i].push_back(0);
	c[0][i] = 1;

	g[i + n].push_back(D); g[D].push_back(i + n);
	c[i + n][D] = 1;
    }
}

int ok = 1;

int bf()
{
    memset(d, 0x3f, sizeof(d));
    memset(inq, 0, sizeof(inq));
    queue<int> Q;
    Q.push(S); d[S] = 0;

    while (!Q.empty())
    {
	int akt = Q.front(); Q.pop();
	for (int i = 0; i < g[akt].size(); ++i)
	{
	    int next = g[akt][i];
	    if (c[akt][next] - f[akt][next] == 0) continue;

	    if (d[next] > d[akt] + cost[akt][next])
	    {
		d[next] = d[akt] + cost[akt][next];
		p[next] = akt;
		if (!inq[next])
		{
		    Q.push(next);
		    inq[next] = 1;
		}
	    }
	}
	inq[akt] = 0;
    }

    if (d[D] != inf)
    {
	ok = 1;
	int minn = inf;
	for (int i = D; i != 0; i = p[i])
	    minn = min(minn, c[p[i]][i] - f[p[i]][i]);
	for (int i = D; i != 0; i = p[i])
	{
	    f[p[i]][i] += minn; 
	    f[i][p[i]] -= minn;
	}

	return minn * d[D];
    }

    return 0;
}

void flux()
{
    int res = 0;
    while (ok) 
    {
	ok = 0;
	res += bf();
    } 
    printf("%d\n", res);
}

int main()
{
    freopen("cc.in","r",stdin);
    freopen("cc.out","w",stdout);

    read();
    flux();

    return 0;
}