Cod sursa(job #614658)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 7 octombrie 2011 04:40:11
Problema Flux maxim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.33 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <limits>
#include <bitset>

#define MAXN 1001

#define minimum(a,b)	\
({						\
	typeof(a) _a = a;	\
	typeof(b) _b = b;	\
	_a<=_b?_a:_b;		\
})

using namespace std;

typedef vector<vector<int> > Graph;

bool BFS
(
	const Graph &graph,
	const int src,
	const int dest,
	int *const* capacity,
	int **flow,
	int *pred
)
{
	bool maxFlowReached;
	bitset<MAXN> passed;
	queue<int> Q;
	int cf;

	maxFlowReached = true;
	passed.reset();
	
	Q.push(src);
	passed[src] = true;

	while (!Q.empty())
	{
		const int node = Q.front();
		Q.pop();
		
		for (int i=0; i<graph[node].size(); ++i)
		{
			cf = capacity[node][graph[node][i]] - flow[node][graph[node][i]];
			if (cf > 0 && !passed[graph[node][i]])
			{
				if (graph[node][i] != dest)
				{
					pred[graph[node][i]] = node;
					Q.push(graph[node][i]);
					passed[graph[node][i]] = true;
				}
				else
				{
					maxFlowReached = false;
				}
			}
		}
	}
	
	return maxFlowReached;
}

int EdmondsKarp
(
	const Graph &graph,
	const int src,
	const int dest,
	int *const* capacity,
	int **flow
)
{
	int *pred;
	int cf;
	int maxFlow = 0;
	pred = new int[graph.size()];
	memset(pred, -1, sizeof(int)*graph.size());

	while (!BFS(graph, src, dest, capacity, flow, pred))
	{
		for (int i=0; i<graph[dest].size(); ++i)
		{
			if (pred[graph[dest][i]] != -1 || graph[dest][i] == src)
			{
				int minCf = minimum(numeric_limits<int>::max(), capacity[graph[dest][i]][dest] - flow[graph[dest][i]][dest]);
				
				//cout << "Found new Path:\n";
				//cout << graph[dest][i]+1 << " " << dest+1 << endl;
				
				int u = pred[graph[dest][i]], v = graph[dest][i];
				while(u != -1)
				{
					minCf = minimum(minCf, capacity[u][v] - flow[u][v]);
					v = u;
					u = pred[u];
				}
				
				flow[graph[dest][i]][dest] += minCf;
				flow[dest][graph[dest][i]] -= minCf;
				u = pred[graph[dest][i]], v = graph[dest][i];
				while(u != -1)
				{
					//cout << u+1 << " " << v+1 << endl;
					
					flow[u][v] += minCf;
					flow[v][u] -= minCf;
					v = u;
					u = pred[u];
				}
				
				maxFlow += minCf;
			}
		}

		//cout << "Done\n\n";
	}
	
	/*cout << endl;
	for (int i=0; i<graph.size(); ++i)
	{
		for (int j=0; j<graph.size(); ++j)
		{
			cout << flow[i][j] << " ";
		}
		cout << endl;
	}*/
	
	delete pred;
	
	return maxFlow;
}

int main()
{
	int n, m;
	int **capacity, **flow;
	Graph graph;
	fstream fin("maxflow.in", fstream::in);
	fstream fout("maxflow.out", fstream::out);

	fin >> n >> m;
	//cout << n << " " << m << endl;

	graph.resize(n);
	capacity = new int*[n];
	flow = new int*[n];
	
	for (int i=0; i<n; ++i)
	{
		capacity[i] = new int[n];
		memset(capacity[i], 0, sizeof(int)*n);
		
		flow[i] = new int[n];
		memset(flow[i], 0, sizeof(int)*n);
	}

	for (int i=0; i<m; ++i)
	{
		int x, y, c;
		fin >> x >> y >> c;
		
		graph[x-1].push_back(y-1);
		graph[y-1].push_back(x-1);
		
		capacity[x-1][y-1] = c;
	}

	/*for (int i=0; i<n; ++i)
	{
		cout << i+1 << ": ";
		for (int j=0; j<graph[i].size(); ++j)
		{
			cout << graph[i][j]+1 << " ";
		}
		cout << endl;
	}*/
	
	cout << EdmondsKarp(graph, 0, n-1, capacity, flow) << "\n";

	fin.close();
	fout.close();
	return 0;
}