Cod sursa(job #612836)

Utilizator claudiumihailClaudiu Mihail claudiumihail Data 10 septembrie 2011 17:59:33
Problema Flux maxim Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 3.2 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;

int EdmondsKarp
(
	const Graph &graph,
	const int src,
	const int dest,
	int *const* capacity,
	int **flow
)
{
	bool maxFlowReached;
	int *pred;
	int cf;
	int maxFlow = 0;
	bitset<MAXN> passed;
	pred = new int[graph.size()];

	do
	{
		queue<int> Q;

		maxFlowReached = true;
		memset(pred, -1, sizeof(int)*graph.size());
		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;
					}
				}
			}
		}
		
		for (int i=0; i<graph[dest].size(); ++i)
		{
			if (pred[graph[dest][i]] != -1 || graph[dest][i] == src)
			{
				maxFlowReached = false;
				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];
				do
				{
					//cout << u+1 << " " << v+1 << endl;
					
					flow[u][v] += minCf;
					flow[v][u] -= minCf;
					v = u;
					u = pred[u];
				} while(u != -1);
			}
		}

		//cout << "Done\n\n";
		
	} while(!maxFlowReached);
	
	/*cout << endl;
	for (int i=0; i<graph.size(); ++i)
	{
		for (int j=0; j<graph.size(); ++j)
		{
			cout << flow[i][j] << " ";
		}
		cout << endl;
	}*/
	
	for (int i=0; i<graph.size(); ++i)
	{
		maxFlow += flow[i][dest];
	}
	
	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;
	}*/
	
	fout << EdmondsKarp(graph, 0, n-1, capacity, flow) << "\n";

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