Cod sursa(job #17923)

Utilizator ProstuStefan-Alexandru Filip Prostu Data 17 februarie 2007 13:43:02
Problema Algola Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.49 kb
#include <cstdio>
#include <queue>
#include <vector>

using namespace std;

#define PB push_back
#define MP make_pair

const int NMAX = 64;
const int INF = 0x3f3f3f3f;

int N, M, T, dest, tmax, nw, maxflow;
int C[NMAX][NMAX];
int F[NMAX][NMAX][NMAX << 1][2];
vector <int> G[NMAX];
pair <int, int> way[NMAX * NMAX << 1];

void read() {
	FILE *fin = fopen("algola.in", "rt");
	int i, u, v, c;

	fscanf(fin, " %d %d", &N, &M);

	tmax = N + M;

	for (i = 1; i <= N; ++i) {
		fscanf(fin, " %d", &c);
		G[0].PB(i); G[i].PB(0);
		C[0][i] = c;
		T += c;
	}
	
	for (i = 0; i < M; ++i) {
		fscanf(fin, " %d %d %d", &u, &v, &c);
		G[u].PB(v); G[v].PB(u);
		C[u][v] = c; C[v][u] = c;
	}

	fclose(fin);
}

void make_way(int u, int t, pair <int, int> T[NMAX][NMAX << 1]) {
	if (T[u][t].first != -1)
		make_way(T[u][t].first, T[u][t].second, T);
	way[nw++] = MP(u, t);
}

bool BFS() {
	queue <pair <int, int> > Q;
	bool V[NMAX][NMAX << 1];
	pair <int, int> T[NMAX][NMAX << 1];
	int u, v, t;
	unsigned i;

	memset(V, 0x00, sizeof(V));

	for (i = 0; (int) i < dest; ++i) {
		Q.push(MP(0, i));
		V[0][i] = true; T[0][i].first = -1;
	}

	for (; !Q.empty(); Q.pop()) {
		u = Q.front().first;
		t = Q.front().second;

		for (i = 0; i < G[u].size(); ++i) {
			v = G[u][i];

			if (C[u][v] > F[u][v][t][1] && t < dest && V[v][t + 1] == false) {
				Q.push(MP(v, t + 1));
				V[v][t + 1] = true;
				T[v][t + 1] = Q.front();

				if (v == 1) {
					nw = 0;
					make_way(1, t + 1, T);
					return true;
				}
			}

			if (0 > F[u][v][t][0] && t > 0 && V[v][t - 1] == false) {
				Q.push(MP(v, t - 1));
				V[v][t - 1] = true;
				T[v][t - 1] = Q.front();

				if (v == 1) {
					nw = 0;
					make_way(1, t - 1, T);
					return false;
				}
			}
		}
	}

	return false;
}

int flux() {
	int i, flow;
	int u, v, t1, t2;

	while (BFS()) {
		flow = INF;
		
		for (i = 1; i < nw; ++i) {
			u = way[i - 1].first; v = way[i].first;
			t1 = way[i - 1].second; t2 = way[i].second;

			if (t2 > t1)
				flow <?= C[u][v] - F[u][v][t1][1];
			else
				flow <?= - F[u][v][t1][0];
		}

		for (i = 1; i < nw; ++i) {
			u = way[i - 1].first; v = way[i].first;
			t1 = way[i - 1].second; t2 = way[i].second;

			if (t2 > t1)	
				F[u][v][t1][1] += flow,
				F[v][u][t2][0] -= flow;
			else
				F[u][v][t1][0] += flow,
				F[v][u][t2][1] -= flow;
		}
		maxflow += flow;
	}

	return maxflow;
}

void write() {
	FILE *fout = fopen("algola.out", "wt");

	for (dest = 1; flux() < T; ++dest);

	fprintf(fout, "%d\n", dest - 1);

	fclose(fout);
}

int main() {
	
	read();

	write();

	return 0;
}