Cod sursa(job #141702)

Utilizator vlad.maneaVlad Manea vlad.manea Data 23 februarie 2008 16:50:42
Problema Critice Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.91 kb
#include <stdio.h>
#include <values.h>

#define nmax 1024
#define mmax 10005

int N, M, ans;

int viz[nmax], cat[nmax], viz1[nmax], vizN[nmax], nod[nmax];

int vec[nmax][nmax], cap[nmax][nmax], indice[nmax][nmax];

int vector[mmax], vector2[mmax];


void read()
{
	int i, A, B, C;

	freopen("critice.in", "r", stdin);
	scanf("%d%d", &N, &M);

	for (i = 1; i <= M; ++i)
	{
		scanf("%d %d %d", &A, &B, &C);

		// fac pentru A
		vec[A][++vec[A][0]] = B;
		cap[A][B] = C;

		// fac pentru B
		vec[B][++vec[B][0]] = A;
		cap[B][A] = C;

		indice[A][B] = indice[B][A] = i;
	}
}

int bfs()
{
	int i, j, m, ic, sc, flux;

	for (i = 2; i <= N; ++i)
		viz[i] = MAXINT;

	viz[1] = -1;
	cat[1] = MAXINT;

	nod[ic = sc = 0] = 1;

	while (ic <= sc)
	{
		i = nod[ic++];

		for (m = 1; m <= vec[i][0]; m++)
		{
			j = vec[i][m];
			if (cap[i][j] > 0 && viz[j] == MAXINT)
			{
				nod[++sc] = j;
				viz[j] = i;
				cat[j] = cat[i] < cap[i][j]? cat[i]: cap[i][j];
			}
		}
	}

	if (viz[N] == MAXINT)
		return 0;

	for (flux = cat[N], j = N; viz[j] != -1; j = viz[j])
	{
		i = viz[j];
		cap[i][j] -= flux;
		cap[j][i] += flux;
	}

	return 1;
}

void bf1()
{
	int i, j, m, ic, sc;

	viz1[1] = 1;

	for (i = 2; i <= N; ++i)
		viz1[i] = MAXINT;

	nod[ic = sc = 0] = 1;

	while (ic <= sc)
	{
		i = nod[ic++];

		for (m = 1; m <= vec[i][0]; ++m)
		{
			j = vec[i][m];
			if (viz1[j] == MAXINT && cap[i][j] > 0)
			{
				nod[++sc] = j;
				viz1[j] = 1;
			}
		}
	}
}

void bfN()
{
	int i, j, m, ic, sc;

	vizN[N] = 1;

	for (i = 1; i < N; ++i)
		vizN[i] = MAXINT;

	nod[ic = sc = 0] = N;

	while (ic <= sc)
	{
		j = nod[ic++];

		for (m = 1; m <= vec[j][0]; ++m)
		{
			i = vec[j][m];
			if (vizN[i] == MAXINT && cap[i][j] > 0)
			{
				nod[++sc] = i;
				vizN[i] = 1;
			}
		}
	}
}

void solve()
{
	int i, j;

	while (bfs());

	bf1();

	bfN();

	for (i = 1; i <= N; ++i)
		for (j = 1; j <= N; ++j)
			if (cap[i][j]==0&&cap[j][i]>0&&i!=j&&viz1[i]==1&&vizN[j]==1)
				++ans;
}

void msort(int, int);

void msort(int l, int r)
{
	if (l >= r) return;

	int m = (l+r)>>1, i, j, k;

	msort(l, m);
	msort(m+1, r);

	for (i = k = l, j = m+1; i <= m && j <= r;)
	{
		if (vector[i] < vector[j])
			vector2[k++] = vector[i++];
		else
			vector2[k++] = vector[j++];
	}

	while (i <= m)
		vector2[k++] = vector[i++];

	while (j <= r)
		vector2[k++] = vector[j++];

	for (k = l; k <= r; ++k)
		vector[k] = vector2[k];
}

void write()
{
	int i, j;

	freopen("critice.out", "w", stdout);
	printf("%d\n", ans);

	for (i = 1; i <= N; ++i)
		for (j = 1; j <= N; ++j)
			if (cap[i][j]==0&&cap[j][i]>0&&i!=j&&viz1[i]==1&&vizN[j]==1)
				vector[++vector[0]] = indice[i][j];

	msort(1, vector[0]);

	for (i = 1; i <= vector[0]; ++i)
		printf("%d\n", vector[i]);
}

int main()
{
	read();
	solve();
	write();

	return 0;
}