Cod sursa(job #132172)

Utilizator plastikDan George Filimon plastik Data 5 februarie 2008 11:50:36
Problema Critice Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.16 kb
#include <cstdio>

const int MAX_N = 1024;
const int INF = 700000;
int C[MAX_N][MAX_N], IC[MAX_N][MAX_N], prev[MAX_N], S[MAX_N * MAX_N], M, N;
int E[MAX_N * MAX_N][2], L[MAX_N][MAX_N], Q[MAX_N * MAX_N];
bool U[MAX_N];

int d1[MAX_N], d2[MAX_N];

bool breadthFirst(int src, int snk) {
	if (src == snk)
		return true;
	
	int i, c, n;
	for (i = 1; i <= N; ++ i) {
		U[i] = false;
		prev[i] = -1;
	}
	U[src] = true;
	
	int st = 0, en = 0;
	Q[en] = src;

	while (st <= en) {
		c = Q[st ++];
		for (i = 1; i <= L[c][0]; ++ i) {
			n = L[c][i];
			if (U[n] == false && C[c][n] > 0) {
				U[n] = true;
				prev[n] = c;
				Q[++ en] = n;
				if (n == snk)
					return true;
			}
		}
	}
	return false;
}

int flowRoute() {
	bool ans = breadthFirst(1, N);
	if (ans == false)
		return 0;
		
	int dif = -1, c;
	for (c = N; prev[c] != -1; c = prev[c])
		if (dif == -1 || C[prev[c]][c] < dif)
			dif = C[prev[c]][c];
			
	if (c != 1 || dif == -1)
		return 0;
		
	for (c = N; prev[c] != -1; c = prev[c]) {
		C[prev[c]][c] -= dif;
		C[c][prev[c]] += dif;
	}
	
	return dif;
}

int main() {
	freopen("critice.in", "r", stdin);
	freopen("critice.out", "w", stdout);
	
	scanf("%d %d", &N, &M);
	int i, j, v1, v2, c;
	for (i = 1; i <= N; ++ i)
		L[i][0] = 0;
	for (i = 0; i < M; ++ i) {
		scanf("%d %d %d", &v1, &v2, &c);
		C[v1][v2] = C[v2][v1] = c;
		L[v1][++ L[v1][0]] = v2;
		L[v2][++ L[v2][0]] = v1;
		E[i][0] = v1;
		E[i][1] = v2;
		IC[v1][v2] = IC[v2][v1] = c;
	}

	int route;
	for (route = flowRoute(); route != 0; route = flowRoute())
		;
	
	for (i = 1; i <= N; ++ i)
		for (j = 1; j <= N; ++ j)
			if (IC[i][j] - C[i][j] > 0)
				C[j][i] = IC[i][j] - C[i][j];
	
	int src = 1, snk = N, ns = 0;	

	for (i = 1; i <= N; i++) {
		d1[i] = breadthFirst(src, i);
		d2[i] = breadthFirst(i, snk);
	}
	for (i = 0; i < M; ++ i) {
		v1 = E[i][0];
		v2 = E[i][1];
		if (C[v2][v1] == IC[v1][v2] && d1[v1] && d2[v2])) {
				S[ns ++] = i + 1;
				continue;
		}		
		if (C[v1][v2] == IC[v2][v1] && d2[v1] && d1[v2]))
				S[ns ++] = i + 1;
	}

	printf("%d\n", ns);
	for (i = 0; i < ns; ++ i)
		printf("%d\n", S[i]);
	
	return 0;
}