Cod sursa(job #970850)

Utilizator tudorv96Tudor Varan tudorv96 Data 7 iulie 2013 22:41:32
Problema Critice Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.43 kb
#include <vector>
#include <set>
#include <queue>
#include <list>
#include <fstream>
#include <iostream>
using namespace std;

#define min(a, b) ((a < b) ? a : b)
#define X first
#define Y second

typedef short sh;
typedef pair <sh, sh> muchie;

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

vector <set <sh> > g;
vector <vector <sh> > f, c, crit;
list <muchie> sol;
vector <sh> t, viz;
queue <sh> Q;
set <sh> res;
sh n, m, vizit;
muchie critica;

int bfsopt() {
	Q.push(1);
	while (Q.size() && viz[n] != vizit) {
		sh x = Q.front();
		Q.pop();
		if (x == critica.X || x == critica.Y) {
			int crt = (x == critica.X) ? critica.Y : critica.X;
			Q.push(crt);
			viz[crt] = vizit;
		} 
		for (set <sh> :: iterator it = g[x].begin(); it != g[x].end(); ++it) 
		if (viz[*it] != vizit) {
			Q.push(*it);
			viz[*it] = vizit;
		}
	}
	while (Q.size())
		Q.pop();
	return viz[n];
}

int bfs() {
	Q.push(1);
	viz[1] = vizit;
	while (Q.size()) {
		sh x = Q.front();
		Q.pop();
		for (set <sh> :: iterator it = g[x].begin(); it != g[x].end(); ++it)
			if (viz[*it] != vizit && f[x][*it] < c[x][*it]) {
				Q.push(*it);
				viz[*it] = vizit;
				t[*it] = x;
			}
	}
	return viz[n];
}	

void Resizeall(int x) {
	t.resize(x); crit.resize(x);
	f.resize(x); c.resize(x);
	viz.resize(x); g.resize(x);
	for (int i = 1; i < x; ++i)
		f[i].resize(x), c[i].resize(x), crit[i].resize(x);
}

int main() {
	fin >> n >> m;
	Resizeall(n+1);
	for (int i = 1; i <= m; ++i) {
		int x, y, z;
		fin >> x >> y >> z;
		g[x].insert(y);
		g[y].insert(x);
		c[x][y] = c[y][x] = z;
		crit[x][y] = crit[y][x] = i;
	}
	fin.close();
	while (++vizit == bfs()) 
		for (int i = 1; i < n; ++i)
			if (f[i][n] < c[i][n]) {
				int MIN = c[i][n] - f[i][n];
				for (int x = i; x != 1; x = t[x])
					MIN = min (c[t[x]][x] - f[t[x]][x], MIN);
				for (int x = i; x != 1; x = t[x]) {
					f[t[x]][x] += MIN;
					f[x][t[x]] -= MIN;
					if (f[t[x]][x] == c[t[x]][x]) {
						sol.push_back (muchie (t[x], x));
						g[t[x]].erase(x);
						g[x].erase(t[x]);
					}
				}
				f[i][n] += MIN;
				f[n][i] += MIN;
				if (f[i][n] == c[i][n]) {
					sol.push_back (muchie (i, n));
					g[i].erase(n);
					g[n].erase(i);
				}
			}
	for (list <muchie> :: iterator it = sol.begin(); it != sol.end(); ++it) {
		critica = *it;
		if (++vizit == bfsopt())
			res.insert(crit[(*it).X][(*it).Y]);
	}
	fout << res.size() << "\n";
	for (set <sh> :: iterator it = res.begin(); it != res.end(); ++it)
		fout << *it << "\n";
	return 0;
}