Cod sursa(job #2648134)

Utilizator MarcGrecMarc Grec MarcGrec Data 8 septembrie 2020 21:03:06
Problema Flux maxim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.86 kb
#define MAX_N 1000
#define MAX_M 5000
#define INF 0x3f3f3f3f

#include <iostream>

#include <fstream>
#include <vector>
#include <utility>
#include <memory>
#include <list>
#include <algorithm>
#include <bitset>
using namespace std;

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

struct A
{
	A(int _node, int _capacity, int _flow) : node(_node), capacity(_capacity), flow(_flow)
	{
	}
	
	int node, capacity, flow;
	A* inverse = nullptr;
};

using UPA = unique_ptr<A>;

int n, m, s, d, maxFlow;
vector<UPA> G[MAX_N + 1];

void Read();
bool Augment(int node);

int main()
{
	Read();
	
	while (Augment(s));
	
	fout << maxFlow;
	
	fin.close();
	fout.close();
	return 0;
}

void Read()
{	
	fin >> n >> m;
	
	// Setting the source and destination
	s = 1;
	d = n;
	
	for (int i = 0; i < m; ++i)
	{
		int x, y, c;
		
		fin >> x >> y >> c;
		
		// Edge from x to y
		UPA xy(new A(y, c, 0));
		
		// Edge from y to x (back edge)
		UPA yx(new A(x, 0, 0));
		
		xy->inverse = yx.get();
		
		yx->inverse = xy.get();
		
		G[x].emplace_back(move(xy));
		
		G[y].emplace_back(move(yx));
	}
}

bitset<MAX_N + 1> V;
list<A*> path;
bool Augment(int node)
{
	if (node == d)
	{
		int mi = INF;
		
		for (A* ptrAdjNode : path)
		{
			mi = min(mi, ptrAdjNode->capacity - ptrAdjNode->flow);
		}
		
		for (A* ptrAdjNode : path)
		{
			ptrAdjNode->flow          += mi;
			ptrAdjNode->inverse->flow -= mi;
		}
		
		maxFlow += mi;
	
		return mi != 0;	
	}
	else
	{
		V[node] = true;
		
		bool foundPath = false;
		
		for (const auto& adjNode : G[node])
		{	
			if (V[adjNode->node])
			{
				continue;
			}
			
			path.push_back(adjNode.get());
			
			if (Augment(adjNode->node))
			{
				foundPath = true;
			}
			
			path.pop_back();
		}
		
		V[node] = false;
		
		return foundPath;
	}
}