Cod sursa(job #88405)

Utilizator mugurelionutMugurel-Ionut Andreica mugurelionut Data 2 octombrie 2007 01:01:25
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
// Time Complexity: O(N^4) = O(N) * O(Bellman-Ford = O(N^3))

#include <stdio.h>
#include <string.h>

#define NMAX 111
#define INF 666666666

int C[2 * NMAX][2 * NMAX], cup[2 * NMAX], f[2 * NMAX][2 * NMAX], tata[2 * NMAX], tip[2 * NMAX], q[2 * NMAX], inq[2 * NMAX], d[2 * NMAX];
int N, sum;

void flux(int start)
{
	int i, j, k, li, ls;

	for (i = 1; i <= 2 * N; i++)
		d[i] = INF,
		inq[i] = 0,
		tata[i] = 0;

	q[li = ls = 0] = start;
	d[start] = 0;
	inq[start] = 1;

	// Bellman-Ford (cu coada)

	while (li != ((ls + 1) % (2 * N)))
	{
		i = q[li];

		if (i <= N) // nod din stanga
		{
			for (j = N + 1; j <= 2 * N; j++)
				if (!f[i][j] && d[i] + C[i][j] < d[j])
				{
					d[j] = d[i] + C[i][j];
					tata[j] = i;
					tip[j] = 1;

					if (!inq[j])
					{
						inq[j] = 1;
						q[ls = ((ls + 1) % (2 * N))] = j;
					}	
				}
		}
		else // nod din dreapta
		{
			if (cup[i] && (d[i] - C[cup[i]][i] < d[cup[i]]))
			{
				d[cup[i]] = d[i] - C[cup[i]][i];
				tata[cup[i]] = i;
				tip[cup[i]] = 2;

				if (!inq[cup[i]])
				{
					inq[cup[i]] = 1;
					q[ls = ((ls + 1) % (2 * N))] = cup[i];
				}
			}
		}

		inq[i] = 0;
		li = (li + 1) % (2 * N);
	}

	d[0] = INF;
	for (j = 0, i = N + 1; i <= 2 * N; i++)
		if (!cup[i] && d[i] < d[j])
			j = i;

	sum += d[j];

	// creste fluxul

	while (tata[j] > 0)
	{
		if (tip[j] == 1)
			f[tata[j]][j]++,
			cup[j] = tata[j];
		else
		{
			f[j][tata[j]]--;
			//fprintf(stderr, "*\n");
		}

		j = tata[j];
	}
}

int main()
{
	int i, j;

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

	scanf("%d", &N);

	for (i = 1; i <= N; i++)
		for (j = 1; j <= N; j++)
			scanf("%d", &C[i][N + j]);

	memset(cup, 0, sizeof(cup));
	memset(f, 0, sizeof(f));

	sum = 0;

	for (i = 1; i <= N; i++)
		flux(i);

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

	return 0;
}