Cod sursa(job #92494)

Utilizator MariusMarius Stroe Marius Data 15 octombrie 2007 19:10:46
Problema Critice Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.7 kb
#include <stdio.h>

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

#define MAX_N 1001
#define MAX_M 10000

int n, *G[MAX_N], m, E[MAX_N][2], deg[MAX_N], C[MAX_N][MAX_N], F[MAX_N][MAX_N];

int Q[MAX_N], P[MAX_N];


void read_in(void)
{
	int x, y, c;

	FILE *fi = fopen(iname, "r");

	fscanf(fi, "%d", &n);
	fscanf(fi, "%d", &m);
	for (int i = 0; i < m; ++ i) 
	{
		fscanf(fi, "%d %d %d", &x, &y, &c);
		C[x][y] = C[y][x] = c;
		E[i][0] = x;
		E[i][1] = y;
		deg[x] ++, deg[y] ++;
	}
	for (int i = 1; i <= n; ++ i) 
	{
		G[i] = new int [deg[i] + 1];
		G[i][deg[i]] = -1;
		deg[i] = 0;
	}
	for (int i = 0; i < m; ++ i) 
	{
		x = E[i][0];
		y = E[i][1];
		G[x][deg[x] ++] = y;
		G[y][deg[y] ++] = x;
	}
	fclose(fi);
}

int BFS(void)
{
	int head, tail;

	for (int i = 2; i <= n; ++ i) 
		P[i] = -1;
	for (Q[head = tail = 0] = 1; head <= tail; ++ head) 
	{
		int x = Q[head];
//		printf("%d ", x);
		for (int *p = G[x]; *p != -1; ++ p) 
		{
			if (P[*p] == -1 && C[x][*p] - F[x][*p] > 0)
			{
				Q[++ tail] = *p;
				P[*p] = x;
				if (*p == n)  
					return 1;
			}
		}
	}
//	printf("\n");
	return 0;
}

void BF1(void)
{
	int head, tail;

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

void BF2(void)
{
	int head, tail;

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

int main(void)
{
	read_in();
	
	while (BFS())
	{
//		printf("BFS\n");
		for (int i = 1; i <= n; ++ i)
		{
			if (P[i] == -1 || C[i][n] <= F[i][n])
				continue ;
			int r = C[i][n] - F[i][n];
			for (int j = i; j != 1; j = P[j])
			{
				if (r > C[P[j]][j] - F[P[j]][j])
					r = C[P[j]][j] - F[P[j]][j];
			}
			if (r == 0)
				continue ;
//			printf("way %d, ", i);
			F[i][n] += r, F[n][i] -= r;
			for (int j = i; j != 1; j = P[j]) 
			{
				F[P[j]][j] += r;
				F[j][P[j]] -= r;
//				printf("%d ", P[j]);
			}
		}
//		printf("\n---\n");
	}

	FILE *fo = fopen(oname, "w");

	for (int i = 1; i <= n; ++ i)
		P[i] = -1;
	BF1();
	BF2();
	int res = 0;
	for (int i = 0; i < m; ++ i) 
	{
		int x = E[i][0];
		int y = E[i][1];
		if (P[x] + P[y] == 3)
			res ++;
	}
	fprintf(fo, "%d\n", res);
	for (int i = 0; i < m; ++ i) 
	{
		int x = E[i][0];
		int y = E[i][1];
		if (P[x] + P[y] == 3)
			fprintf(fo, "%d\n", i + 1);
	}
	fclose(fo);

	return 0;
}