Cod sursa(job #85011)

Utilizator MariusMarius Stroe Marius Data 19 septembrie 2007 16:54:05
Problema Critice Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.51 kb
#include <stdio.h>
#include <memory.h>

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

#define MAXN  1007
#define MAXM  10007
#define MIN(a, b) ((a) < (b) ? (a) : (b))

int *G[MAXN], gr[MAXN], x[MAXN], y[MAXN], C[MAXN][MAXN], F[MAXN][MAXN], Q[MAXN], T[MAXN], mark[MAXN];

int n, n_edges;


void read_in(void)
{
	int cap;

	FILE *fi = fopen(iname, "r");
	
	fscanf(fi, "%d %d", &n, &n_edges);
	for (int i = 0; i < n_edges; ++ i) {
		fscanf(fi, "%d %d %d", &x[i], &y[i], &cap);
		C[x[i]][y[i]] = C[y[i]][x[i]] = cap;
		gr[x[i]] ++;
		gr[y[i]] ++;
	}
	fclose(fi);
	for (int i = 1; i <= n; ++ i) {
		G[i] = new int[gr[i] + 1];
		G[i][gr[i]] = -1;
		gr[i] = 0;
	}
	for (int i = 0; i < n_edges; ++ i) {
		G[x[i]][gr[x[i]] ++] = y[i];
		G[y[i]][gr[y[i]] ++] = x[i];
	}
}

int bfs(void)
{
	int cap, coada;

	Q[cap = coada = 0] = 1;
	for (int i = 2; i <= n; ++ i)
		T[i] = -1;
	for (; cap <= coada; ++ cap) {
		int x = Q[cap];
		for (int *p = G[x]; *p != -1; ++ p) {
			if (T[*p] == -1 && (C[x][*p] - F[x][*p] > 0)) {
				Q[++ coada] = *p;
				T[*p] = x;
				if (*p == n)
					return 1;
			}
		}
	}
	return 0;
}

void dinic(void)
{
	while (bfs()) {
		for (int i = 1; i <= n; ++ i) {
			if (T[i] == -1)  
				continue ;
			if (C[i][n] <= F[i][n])
				continue ;
			
			int r = C[i][n] - F[i][n];
			for (int j = i; j != 1; j = T[j])
				r = MIN(r, C[T[j]][j] - F[T[j]][j]);

			if (r == 0)
				continue ;
			
			F[i][n] += r, F[n][i] -= r;
			for (int j = i; j != 1; j = T[j]) {
				F[T[j]][j] += r;
				F[j][T[j]] -= r;
			}
		}
	}
}

void bf1(void)
{
	int cap, coada;

	Q[cap = coada = 0] = 1;
	mark[1] = 1;
	for (; cap <= coada; ++ cap) {
		int x = Q[cap];
		for (int *p = G[x]; *p != -1; ++ p)
			if (mark[*p] == 0 && (C[x][*p] - F[x][*p] > 0)) {
				mark[*p] = 1;
				Q[++ coada] = *p;
			}
	}
}

void bf2(void)
{
	int cap, coada;

	Q[cap = coada = 0] = n;
	mark[n] = 2;
	for (; cap <= coada; ++ cap) {
		int x = Q[cap];
		for (int *p = G[x]; *p != -1; ++ p)
			if (mark[*p] == 0 && (C[*p][x] - F[*p][x] > 0)) {
				mark[*p] = 2;
				Q[++ coada] = *p;
			}
	}
}


int main(void)
{
	read_in();
	dinic();
	
	bf1(), bf2();

	FILE *fo = fopen(oname, "w");
	int rez = 0;
	
	for (int i = 0; i < n_edges; ++ i)
		if (mark[x[i]] + mark[y[i]] == 3)
			rez ++;
	fprintf(fo, "%d\n", rez);
	for (int i = 0; i < n_edges; ++ i)
		if (mark[x[i]] + mark[y[i]] == 3)
			fprintf(fo, "%d\n", i + 1);
	fclose(fo);

	return 0;
}