Cod sursa(job #169)

Utilizator MariusMarius Stroe Marius Data 5 decembrie 2006 23:52:58
Problema Algola Scor 100
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 MIN(const int z, const int w) {
	return (z < w ? z : w);
}

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

void read_data(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 x, xcd;
	int y, ycd;
	int i;
	int k;
	int t;
	int l, r;
	int fnd = 0;
	
	memset(F, 0, sizeof(F));

	for (F[Q[l = r = 0] = 0] = MAX_FLOW; l <= r && !fnd; ++l) {
		x = Q[l] % 51;
		t = Q[l] / 51;
		xcd = code(x, t);

		for (i = G[x][0]; i > 0 && !fnd; --i) {
			ycd = code(G[x][i], t + 1);
			
			if (t <= 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;
				}
			}
		}
		ycd = code(x, t + 1);

		if (t <= TIME && F[ycd] == 0 && C[xcd][ycd]) {
			F[ycd] = MIN(F[xcd], C[xcd][ycd]);
			Q[++r] = ycd;
			P[ycd] = xcd;
		}
	}
	if (fnd == 0)
		return 0;

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

	CRF += hey;
	for (x = sink, t = fnd; x > 0; ) {
		k = code(x, t);
		
		C[ P[k] ][k] -= hey;
		C[k][ P[k] ] += hey;

		x = P[k] % 51;
		t = P[k] / 51;
	}
	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(i, 0);
		add(0, i);
	}
	/* 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_data();
	
	freopen(oname, "w", stdout);
	
	printf("%d\n", solve());

	return 0;
}