Cod sursa(job #2051875)

Utilizator vladm98Munteanu Vlad vladm98 Data 29 octombrie 2017 17:34:38
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.11 kb
#include <bits/stdc++.h>

using namespace std;

class MaxFlow
{
public:
	int GetFlow(int n, vector <pair<pair<int, int>, int>> Edges, int Source, int Target)
	{
		return SolveOneGraph(n, Edges, Source, Target);
	}

private:
	//DECLARATIONS
	vector<vector<int>> Capacity;
	vector<vector<int>> Flow;
	vector<vector<int>> Graph;
	queue<int> Bellman_Ford;
	vector <int> Father;
	int Source, Target, NumberOfNodes, MaximumFlow;
	//DECLARATIONS

	//START CLASS
	void Start (int n, vector <pair<pair<int, int>, int>> Edges, int S, int T)
	{
		MaximumFlow = 0;
		Source = S;
		Target = T;
		NumberOfNodes = n;
		Capacity.resize(NumberOfNodes + 1);
		Flow.resize(NumberOfNodes + 1);
		Graph.resize(NumberOfNodes + 1);
		Father.resize(NumberOfNodes + 1);
		for (int Node = 1; Node <= NumberOfNodes; ++Node)
		{
			Capacity[Node].resize(NumberOfNodes + 1, 0);
			Flow[Node].resize(NumberOfNodes + 1, 0);
		}
		for (auto Edge : Edges)
		{
			int From = Edge.first.first;
			int To = Edge.first.second;
			int EdgeCapacity = Edge.second;
			
			//NORMAL GRAPH
			Capacity[From][To] += EdgeCapacity;
			Graph[From].push_back(To);
			//NORMAL GRAPH

			//RESIDUAL GRAPH
			Graph[To].push_back(From);
			//RESIDUAL GRAPH
		}
	}
	//START CLASS

	//TRY TO PUSH MORE FLOW TO TARGET
	bool TryFlow ()
	{
		fill(Father.begin(), Father.end(), 0);
		Father[Source] = Source;
		Bellman_Ford.push(Source);
		while (Bellman_Ford.size())
		{
			int CurrentNode = Bellman_Ford.front();
			Bellman_Ford.pop();
			if (CurrentNode == Target)
				continue;
			for (auto x:Graph[CurrentNode])
			{
				if (Father[x] == 0 && Flow[CurrentNode][x] < Capacity[CurrentNode][x])
				{
					Father[x] = CurrentNode;
					Bellman_Ford.push(x);
				}
			}
		}
		if (Father[Target] == 0)
			return false;
		return true;
	}
	//TRY TO PUSH MORE FLOW TO TARGET

	//UPDATE FLOW
	void UpdateFlow()
	{
		for (auto x:Graph[Target])
		{
			if(Father[x] == 0) continue;
			if(Capacity[x][Target] == Flow[x][Target]) continue;
			Father[Target] = x;
			int CurrentNode = Target;
			int MinimumFlow = (1<<30);
			while (CurrentNode != Source)
			{
				MinimumFlow = min(MinimumFlow, Capacity[Father[CurrentNode]][CurrentNode] - Flow[Father[CurrentNode]][CurrentNode]);
				CurrentNode = Father[CurrentNode];
			}
			CurrentNode = Target;
			while (CurrentNode != Source)
			{
				Flow[Father[CurrentNode]][CurrentNode] += MinimumFlow;
				Flow[CurrentNode][Father[CurrentNode]] -= MinimumFlow;
				CurrentNode = Father[CurrentNode];
			}
			// assert (MinimumFlow > 0);
			MaximumFlow += MinimumFlow;
		}
	}
	//UPDATE FLOW

	//GIVE ME FLOW
	int SolveOneGraph (int n, vector <pair<pair<int, int>, int>> Edges, int Source, int Target)
	{
		Start(n, Edges, Source, Target);
		while(TryFlow())
			UpdateFlow();
		return MaximumFlow;
	}
	//GIVE ME FLOW
};

vector <pair<pair<int, int>, int>> Edges;
int main(int argc, char const *argv[])
{
	ifstream fin ("maxflow.in");
	ofstream fout ("maxflow.out");

	MaxFlow *Flow = new MaxFlow;
	int n, m;
	fin >> n >> m;
	for (int i = 1; i <= m; ++i)
	{
		int x, y, Capacity;
		fin >> x >> y >> Capacity;
		Edges.push_back({{x, y}, Capacity});
	}
	fout << Flow -> GetFlow(n, Edges, 1, n);
	return 0;
}