Cod sursa(job #2698065)

Utilizator MarcGrecMarc Grec MarcGrec Data 20 ianuarie 2021 20:03:34
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.9 kb
#define MAX_N 1000

#define INF 0x3f3f3f3f

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

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

struct A
{
	int nod, capacitate, flux;
	
	A* invers;
};

int n, m, fluxMaxim;
vector<unique_ptr<A>> G[MAX_N + 1];

int L[MAX_N + 1];

bool Bfs();

void Augmenteaza();

void FluxMaxim();

int main()
{
	fin >> n >> m;
	
	for (int i = 1; i <= m; ++i)
	{
		int x, y, z;
		
		fin >> x >> y >> z;
		
		unique_ptr<A> u(new A), v(new A);
		
		u->nod        = y;
		u->capacitate = z;
		u->flux 	  = 0;
		u->invers     = v.get();
		
		v->nod        = x;
		v->capacitate = 0;
		v->flux       = 0;
		v->invers     = u.get();
		
		G[x].push_back(move(u));
		
		G[y].push_back(move(v));
	}
	
	FluxMaxim();
	
	fout << fluxMaxim;
	
	fin.close();
	fout.close();
	return 0;
}

bool Bfs()
{
	for (int i = 1; i <= n; ++i)
	{
		L[i] = -1;
	}
	
	L[1] = 1;
	
	queue<int> Q;
	
	Q.push(1);
	
	while (!Q.empty())
	{
		int nod = Q.front();
		Q.pop();
		
		for (const auto& u : G[nod])
		{
			if ((L[u->nod] == -1) && (u->capacitate > u->flux))
			{
				L[u->nod] = L[nod] + 1;
				
				Q.push(u->nod);
			}
		}
	}
	
	return L[n] != -1;
}

list<A*> path;

void Augmenteaza(int nod)
{
	if (nod == n)
	{
		int minFlow = INF;
		
		for (const auto& u : path)
		{
			minFlow = min(minFlow, u->capacitate - u->flux);
		}
		
		for (auto& u : path)
		{
			u->flux         += minFlow;
			u->invers->flux -= minFlow;
		}
		
		fluxMaxim += minFlow;
	}
	else
	{
		for (const auto& u : G[nod])
		{
			if (L[u->nod] == (L[nod] + 1))
			{
				path.push_back(u.get());
				Augmenteaza(u->nod);
				path.pop_back();
			}
		}
	}
}

void FluxMaxim()
{	
	while (Bfs())
	{
		Augmenteaza(1);
	}
}