Cod sursa(job #12499)

Utilizator MariusMarius Stroe Marius Data 4 februarie 2007 11:01:30
Problema Algola Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.71 kb
#include <cstdio>
#include <memory>
using namespace std;

const char iname[] = "algola.in";
const char oname[] = "algola.out";

#define  MAX_N  51
#define  MAX_T  101
#define  MAX_NT MAX_N * MAX_T + MAX_T

int  N, A[MAX_N];

int  G[MAX_N][MAX_N];

int  K[MAX_N][MAX_N];

char C[MAX_NT][MAX_NT], F[MAX_NT];

int  Q[MAX_NT], P[MAX_NT];

int  MAX_FLOW, CRF, TIME, sink;


inline void add(const int x, const int y) {
	G[x][++ G[x][0]] = y;
}

inline int code(const int x, const int t) {
	return (t * MAX_N + x);
}

inline int MIN(const int a, const int b) {
	if (a < b)	return a;
	return b;
}

void read_in(void)
{
	freopen(iname, "r", stdin);
	int M;
	int i;
	int x, y, c;
	for (scanf("%d %d", & N, & M), i = 1; i <= N; ++i) {
		scanf("%d", A + i);
		MAX_FLOW += A[i];
	}
	for (i = 0; i < M; ++i) {
		scanf("%d %d %d", & x, & y, & c);
		K[x][y] = K[y][x] = c;
		add(x, y);
		add(y, x);
	}
}

int BFS(void)
{
	int l;
	int r;
	int fnd = 0;
	memset(F, 0, sizeof(F));
	
	for (Q[l = r = 0] = 0, F[0] = MAX_FLOW; (l <= r) && (!fnd); ++l) {
		int x = Q[l] % MAX_N;
		int t = Q[l] / MAX_N;
		int xcd = Q[l];

		for (int i = G[x][0]; (i > 0) && (!fnd); --i) {
			int ycd = code(G[x][i], t + 1);

			if ((t - 1 <= TIME) && (F[ycd] == 0) && (C[xcd][ycd])) {
				F[ycd] = MIN(F[xcd], C[xcd][ycd]);
				Q[++r] = ycd;
				P[ycd] = xcd;
				if (G[x][i] == sink) {
					fnd = t + 1;
					break ;
				}
			}
			ycd = code(G[x][i], t - 1);
			
			if ((t > 0) && (F[ycd] == 0) && (C[xcd][ycd])) {
				F[ycd] = MIN(F[xcd], C[xcd][ycd]);
				Q[++r] = ycd;
				P[ycd] = xcd;
				if (G[x][i] == sink) {
					fnd = t - 1;
					break ;
				}
			}
		}
		int ycd = code(x, t + 1);
	
		if ((t - 1 <= TIME) && (F[xcd] == 0) && (C[xcd][ycd] != 0)) {
			F[ycd] = MIN(F[xcd], C[xcd][ycd]);
			Q[++r] = ycd;
			P[ycd] = xcd;
		}
	}
	if (fnd == 0)
		return 0;

	int x = sink;
	int t = fnd;
	int hey = F[code(x, t)];

	CRF += hey;

	for (; x > 0; ) {
		int k = code(x, t);
		C[ P[k] ][k] -= hey;
		C[k][ P[k] ] += hey;
		x = P[k] % MAX_N;
		t = P[k] / MAX_N;
	}
	return 1;
}

int solve(void)
{
	int i;
	int j;
	int k;

	/* destinatia */
	sink = 1;
	/* leg toate nodurile de o sursa */
	for (i = 2; i <= N; ++i) {
		C[code(0, 0)][code(i, 1)] = A[i];
		add(0, i);
		add(i, 0);
	}
	/* graful in timp */
	for (i = 1; i <= N; ++i) {
		for (j = 0; j < MAX_T; ++j) {
			C[code(i, j)][code(i, j + 1)] = MAX_FLOW;
			for (k = G[i][0]; k > 0; --k)
				C[code(i, j)][code(G[i][k], j + 1)] = K[i][ G[i][k] ];
		}
	}
	for (TIME = 1; CRF < MAX_FLOW; ++ TIME)
		for (; BFS(); )
			;
	return TIME - 1;
}

int main(void)
{
	read_in();
	printf("%d", solve());
	return 0;
}