Cod sursa(job #148807)

Utilizator ProstuStefan-Alexandru Filip Prostu Data 4 martie 2008 20:40:00
Problema Critice Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.04 kb
#include <cstdio>
#include <cassert>
#include <queue>
#include <vector>

using namespace std;

#define PB push_back

const int NMAX = 1024;
const int MMAX = 10240;
const int INF = 0x3f3f3f3f;

int N, M, A[MMAX], B[MMAX], E[MMAX], H[NMAX];
int C[NMAX][NMAX], F[NMAX][NMAX], W[NMAX][NMAX];
vector <int> G[NMAX];
bool V[NMAX];

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

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

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

	fclose(fin);
}

void preflux(void) {
	queue <int> Q;
	int u, df, hmin;
	vector <int> :: iterator k;

	for (k = G[1].begin(); k != G[1].end(); ++k) {
		E[*k] = F[1][*k] = C[1][*k];
		F[*k][1] = - C[*k][1];
		Q.push(*k);
	}

	H[1] = N;
	for (; !Q.empty(); Q.pop()) {
		V[ u = Q.front() ] = false;
		hmin = 2 * N;

		assert(E[u] != 0);

		for (k = G[u].begin(); k != G[u].end(); ++k) {
			if (C[u][*k] <= F[u][*k]) continue;

			if (H[u] == H[*k] + 1) {
				df = min(E[u], C[u][*k] - F[u][*k]);
				F[u][*k] += df;
				F[*k][u] -= df;

				E[u] -= df; 
				E[*k] += df;

				if (!V[*k] && *k != 1 && *k != N) {
					V[*k] = true;
					Q.push(*k);
				}
			} else {
				hmin = min(hmin, H[*k] + 1);
			}
		}

		if (E[u]) {
			V[u] = true;
			Q.push(u);
			H[u] = hmin;
		}
	}
}

void DFS(int i, int mark) {
	if (V[i]) return;
	vector <int> :: iterator k;

	V[i] = true;
	for (k = G[i].begin(); k != G[i].end(); ++k)
		if ((mark == 1 && F[i][*k] < C[i][*k]) ||
		    (mark == 2 && F[*k][i] < C[*k][i])) {
			DFS(*k, mark);
		} else {
			W[i][*k] |= mark;
			W[*k][i] |= mark;
		}
}

void write(void) {
	FILE *fout = fopen("critice.out", "wt");
	int i, cnt;

	for (cnt = 0, i = 1; i <= M; ++i)
		if (W[ A[i] ][ B[i] ] == 3)
			++cnt;
	
	fprintf(fout, "%d\n", cnt);
	for (i = 1; i <= M; ++i)
		if (W[ A[i] ][ B[i] ] == 3)
			fprintf(fout, "%d\n", i);

	fclose(fout);
}

int main(void) {

	read();

	preflux();

	memset(V, 0x00, sizeof(V));
	DFS(1, 1);
	memset(V, 0x00, sizeof(V));
	DFS(N, 2);

	write();

	return 0;
}