Cod sursa(job #200026)

Utilizator andrei.12Andrei Parvu andrei.12 Data 21 iulie 2008 18:08:48
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.62 kb
#include<stdio.h>
#include<vector>
#include<algorithm>
#include<queue>

using namespace std;

#define lg 300
#define pb push_back
#define infinit 0x3f3f3f3f

int n, i, j, cost, cnt[lg], pred[lg], d[lg][lg], cp[lg][lg];
bool fst[lg];
vector<int> v[lg];

int find(){
	int x, i, val;

	memset(fst, 0, sizeof(fst)), memset(cnt, 0x3f, sizeof(cnt)), memset(pred, 0xff, sizeof(pred));

	queue<int> q;
	q.push(0);
	fst[0] = 1, cnt[0] = 0;

	while (!q.empty()){
		x = q.front(), q.pop();

		for (i = 0; i < (int)v[x].size(); i ++)
			if (cp[x][v[x][i]] > 0 && cnt[x] + d[x][v[x][i]] < cnt[v[x][i]]){
				cnt[v[x][i]] = cnt[x] + d[x][v[x][i]];
				pred[v[x][i]] = x;

				if (!fst[v[x][i]]){
					fst[v[x][i]] = 1;
					q.push(v[x][i]);
				}
			}
		fst[x] = 0;
	}
/*
	for (i = 1; i <= n; i ++)
		printf("%d ", pred[i]);
*/
	val = infinit; x = 2*n+1;
	while (pred[x] != -1){
		val = min(val, cp[pred[x]][x]);

		x = pred[x];
	}

	if (val == infinit)
		return 0;

	x = 2*n+1;
	while (pred[x] != -1){
		cp[pred[x]][x] -= val;
		cp[x][pred[x]] += val;

		d[x][pred[x]] = -d[pred[x]][x];

		x = pred[x];
	}
	
	cost += cnt[2*n+1];

	return val;
}

int flux(){
	int x;

	while (1){
		x = find();

		if (!x)
			break;
	}

	return cost;
}

int main()
{
	freopen("cc.in", "rt", stdin);
	freopen("cc.out", "wt", stdout);

	scanf("%d", &n);
	for (i = 1; i <= n; i ++)
		for (j = 1; j <= n; j ++){
			scanf("%d", &d[i][n+j]);
			d[n+j][i] = -d[i][n+j];

			v[i].pb(n+j), v[n+j].pb(i);

			cp[i][n+j] = 1;
		}

	for (i = 1; i <= n; i ++){
		v[0].pb(i), v[i].pb(0);
		cp[0][i] = 1;

		v[i+n].pb(2*n+1), v[2*n+1].pb(i+n);
		cp[i+n][2*n+1] = 1;
	}

	printf("%d\n", flux());

	return 0;
}