Cod sursa(job #569013)

Utilizator mottyMatei-Dan Epure motty Data 31 martie 2011 21:34:54
Problema Critice Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <fstream>
#include <cstring>
#include <cstdlib>
#include <queue>

using namespace std;

ifstream in("critice.in");
ofstream out("critice.out");

struct edge{
	int x, y;
};

const int N = 1001;
const int M = 10001;
const int INF = 0x3f3f3f;

int n, m;
int ces[N]; // critic edges
int fat[N];
int c[N][N];
int f[N][N];

bool vis[N];
bool sCon[N];
bool dCon[N];

edge edges[M];

void Read()
{
	in >> n >> m;

	for (int i = 1; i <= m; ++i)
	{
		int cap;

		in >> edges[i].x >> edges[i].y >> cap;

		c[edges[i].x][edges[i].y] = cap;
		c[edges[i].y][edges[i].x] = cap;
	}
}

bool BFS()
{
	queue <int> q;
	memset(vis, 0, sizeof(vis));

	q.push(1);
	vis[1] = true;

	while (!q.empty())
	{
		int node = q.front();

		for (int i = 1; i <= n; ++i)
			if (!vis[i] && c[node][i] - f[node][i] > 0)
			{
				vis[i] = true;
				fat[i] = node;

				q.push(i);
			}

		q.pop();
	}

	return vis[n];
}

void GetMinFlow()
{
	while (BFS())
	{
		int minFlow = INF;
		int node;
		
		node = n;

		while (node != 1)
		{
			if (c[fat[node]][node] - f[fat[node]][node] < minFlow)
				minFlow = c[fat[node]][node] - f[fat[node]][node];

			node = fat[node];
		}

		node = n;

		while (node != 1)
		{
			f[fat[node]][node] += minFlow;
			f[node][fat[node]] -= minFlow;

			node = fat[node];
		}
	}
}

void Spread(int node)
{
	for (int i = 1; i <= n; ++i)
		if (!sCon[i] && c[node][i] - f[node][i] > 0)
		{
			sCon[i] = true;
			Spread(i);
		}
}

void RevSpread(int node)
{
	for (int i = 1; i <= n; ++i)
		if (!dCon[i] && c[node][i] - f[node][i] > 0)
		{
			dCon[i] = true;
			RevSpread(i);
		}
}

int GetCriticEdges()
{
	int result = 0;

	for (int i = 1; i <= m; ++i)
		if (c[edges[i].x][edges[i].y] - f[edges[i].x][edges[i].y] == 0)
		{
			if (sCon[edges[i].x] && dCon[edges[i].y])
				++result;
			else if (sCon[edges[i].y] && dCon[edges[i].x])
				++result;
		}

	return result;
}

void PrintCriticEdges()
{
	for (int i = 1; i <= m; ++i)
		if (c[edges[i].x][edges[i].y] - f[edges[i].x][edges[i].y] == 0)
		{
			if (sCon[edges[i].x] && dCon[edges[i].y])
				out << i << "\n";
			else if(sCon[edges[i].y] && dCon[edges[i].x])
				out << i << "\n";
		}
}

int main()
{
	Read();

	GetMinFlow();

	sCon[1] = dCon[n] = true;
	Spread(1);
	RevSpread(n);

	out << GetCriticEdges() << "\n";
	PrintCriticEdges();

	return 0;
}