Cod sursa(job #474068)

Utilizator darrenRares Buhai darren Data 2 august 2010 13:18:45
Problema Critice Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <cstring>
#include <fstream>
#include <algorithm>
#include <iterator>
#include <queue>
#include <vector>

using namespace std;

const int INF = 1 << 30;

int n, m;
int c[1001][1001], f[1001][1001], t[1001];
bool s[1001], can[2][1001], now;
queue<int> q;
vector<int> w[1001], sol;
vector<pair<int, int> > ms;


inline int abs(int x)
{
	return x < 0 ? -x : x;
}
bool bfs();
void dim();
void bfs2(int i);

int main()
{
	ifstream fin("critice.in");
	ofstream fout("critice.out");
	fin >> n >> m;

	ms.resize(m + 1);
	for (int i = 1, n1, n2, cap; i <= m; ++i)
	{
		fin >> n1 >> n2 >> cap;
		c[n1][n2] = cap;
		c[n2][n1] = cap;
		w[n1].push_back(n2);
		w[n2].push_back(n1);
		ms[i] = make_pair(n1, n2);
	}
	while (bfs())
		dim();

	bfs2(1);
	++now;
	bfs2(n);
	for (int i = 1; i <= m; ++i)
		if ((can[0][ms[i].first] == true && can[1][ms[i].second] == true) || (can[0][ms[i].second] == true && can[1][ms[i].first] == true))
			if (c[ms[i].first][ms[i].second] != 0)
				if (c[ms[i].first][ms[i].second] == abs(f[ms[i].first][ms[i].second]))
					sol.push_back(i);

	fout << sol.size() << '\n';
	copy(sol.begin(), sol.end(), ostream_iterator<int>(fout, "\n"));

	fin.close();
	fout.close();

}

bool bfs()
{
	memset(t, 0, sizeof(t));
	memset(s, 0, sizeof(s));
	while (!q.empty()) q.pop();

	q.push(1);
	while (!q.empty())
	{
		int i = q.front(); q.pop();
		for (int j = 1; j <= n; ++j)
			if (!s[j])
				if (f[i][j] < c[i][j])
				{
					t[j] = i, s[j] = true;
					q.push(j);
					if (j == n) return true;
				}
	}
	return false;
}

void dim()
{
	int j = n, i = n, cr = INF;
	while (j != 1)
	{
		i = t[j];
		cr = min(cr, c[i][j] - f[i][j]);
		j = i;
	}
	j = n, i = n;
	while (j != 1)
	{
		i = t[j];
		f[i][j] += cr;
		f[j][i] -= cr;
		j = i;
	}
}

void bfs2(int i)
{
	memset(s, 0, sizeof(s));
	while (!q.empty()) q.pop();
	q.push(i);
	s[i] = true;
	can[now][i] = true;

	while (!q.empty())
	{
		int j = q.front(); q.pop();
		for (int k = 0; k < w[j].size(); ++k)
			if (s[w[j][k]] == false && c[j][w[j][k]] != 0 && abs(f[j][w[j][k]]) < c[j][w[j][k]])
			{
				s[w[j][k]] = true;
				can[now][w[j][k]] = true;
				q.push(w[j][k]);
			}
	}
}