Cod sursa(job #552625)

Utilizator feelshiftFeelshift feelshift Data 12 martie 2011 17:15:02
Problema Critice Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.23 kb
// http://infoarena.ro/problema/critice
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

#define maxNodes 1001
#define maxEdges 10001
#define INFINITY 0x3f3f3f3f
#define from first
#define to second
#define source 1

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

int destination,edges;
bool visitFromSource[maxNodes];
bool visitFromDestination[maxNodes];
int father[maxNodes];
int capacity[maxNodes][maxNodes];
int currentFlow[maxNodes][maxNodes];
pair<int,int> edge[maxEdges];
int critical[maxEdges];
vector<int> graph[maxNodes];

void maxFlow();
bool breadthFirst();
void depthFirst(int node,bool visit[]);

int main() {
	in >> destination >> edges;

	int from,to,flow;
	for(int i=1;i<=edges;i++) {
		in >> from >> to >> flow;
		edge[i] = make_pair(from,to);

		capacity[from][to] = flow;
		capacity[to][from] = flow;

		graph[from].push_back(to);
		graph[to].push_back(from);
	}

	maxFlow();

	depthFirst(source,visitFromSource);
	depthFirst(destination,visitFromDestination);

	for(int i=1;i<=edges;i++)
		if( (visitFromSource[edge[i].from] && visitFromDestination[edge[i].to]) || (visitFromSource[edge[i].to] && visitFromDestination[edge[i].from]) )
			critical[++critical[0]] = i;

	out << critical[0] << "\n";
	for(int i=1;i<=critical[0];i++)
		out << critical[i] << "\n";

	/*for(int i=1;i<=destination;i++)
		out << visitFromSource[i] << " ";
	out << "\n";

	for(int i=1;i<=destination;i++)
		out << visitFromDestination[i] << " ";
	out << "\n";*/

	in.close();
	out.close();

	return (0);
}

void maxFlow() {
	int maxFlow = 0;
	vector<int>::iterator it,end;

	for(int i=1;i<=destination;i++)
		memset(currentFlow[i],0,sizeof(currentFlow[i]));

	while(breadthFirst()) {
		end = graph[destination].end();

		for(it=graph[destination].begin();it!=end;++it)
			if(visitFromSource[*it] && capacity[*it][destination] != currentFlow[*it][destination]) {
				int minFlow = INFINITY;

				father[destination] = *it;

				for(int node=destination;node!=source;node=father[node])
					minFlow = min(minFlow,capacity[father[node]][node] - currentFlow[father[node]][node]);

				if(minFlow) {
					for(int node=destination;node!=source;node=father[node]) {
						currentFlow[father[node]][node] += minFlow;
						currentFlow[node][father[node]] -= minFlow;
					}

					maxFlow += minFlow;
				}
			}
	}

	memset(visitFromSource,0,sizeof(visitFromSource));
}

bool breadthFirst() {
	memset(visitFromSource,false,sizeof(visitFromSource));
	visitFromSource[source] = true;

	int node;
	vector<int>::iterator it,end;

	queue<int> myQueue;
	myQueue.push(source);

	while(!myQueue.empty()) {
		node = myQueue.front();
		myQueue.pop();

		if(node == destination)
			continue;

		end = graph[node].end();
		for(it=graph[node].begin();it!=end;++it)
			if(!visitFromSource[*it] && currentFlow[node][*it] < capacity[node][*it]) {
				visitFromSource[*it] = true;
				myQueue.push(*it);
				father[*it] = node;
			}
	}

	return visitFromSource[destination];
}

void depthFirst(int node,bool visit[]) {
	visit[node] = true;

	vector<int>::iterator it,end;
	end = graph[node].end();

	for(it=graph[node].begin();it!=end;++it)
		if(!visit[*it] && capacity[node][*it] > currentFlow[node][*it] && capacity[*it][node] > currentFlow[*it][node])
			depthFirst(*it,visit);
}