Cod sursa(job #2648049)

Utilizator MarcGrecMarc Grec MarcGrec Data 8 septembrie 2020 15:02:44
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.77 kb
#define MAX_N 1000
#define INF 0x3f3f3f3f
 
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>
#include <algorithm>
using namespace std;
 
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
 
struct edge
{
	int u, v, flow, capacity;
	edge* reverse;
};
 
struct edgestacknode
{
	edgestacknode(edge* _e) :
		e(_e)
	{
	}
	
	edge* e;
	edgestacknode* prev = nullptr;
};
 
struct edgestack
{	
	~edgestack()
	{
		while (!Empty())
		{
			Pop();
		}
	}
	
	edgestacknode* top = nullptr;
	
	void Push(edgestacknode* node)
	{
		edgestacknode* prev = top;
		top                 = node;
		top->prev           = prev;
	}
	
	void Pop()
	{
		edgestacknode* prev = top->prev;
		delete top;
		top = prev;
	}
	
	bool Empty() const
	{
		return top == nullptr;
	}
};
 
int n, m, maxFlow, L[MAX_N + 1];
vector<edge*> G[MAX_N + 1];
bitset<MAX_N + 1> E;
 
void Read();
bool Bfs();
bool Augment(int node);
 
int main()
{
	Read();
	
	while (true)
	{
		E.set();
		if (!Bfs())
		{
			break;
		}
		
		Augment(1);
	}
	
	// Cleanup.
	for (int i = 1; i <= n; ++i)
	{
		for (edge* ptr : G[i])
		{
			delete ptr;
		}
		G[i].clear();
	}
	
	fout << maxFlow;
	
	fin.close();
	fout.close();
	return 0;
}
 
void Read()
{
	fin >> n >> m;
	
	for (int i = 0, x, y, c; i < m; ++i)
	{
		fin >> x >> y >> c;
		
		edge* a     = new edge;
		a->u        = x;
		a->v        = y;
		a->flow     = 0;
		a->capacity = c;
		
		edge* b 	= new edge;
		b->u		= y;
		b->v		= x;
		b->flow		= 0;
		b->capacity = 0;
		
		a->reverse = b;
		b->reverse = a;
		
		G[x].push_back(a);
		G[y].push_back(b);
	}
}
 
bool Bfs()
{
	for (int i = 1; i <= n; ++i)
	{
		L[i] = INF;
	}
	
	queue<int> Q;
	Q.push(1);
	L[1] = 1;
	
	while (!Q.empty())
	{
		int curr = Q.front();
		Q.pop();
		
		for (edge* e : G[curr])
		{
			if (E[e->v] && (L[e->v] > (L[curr] + 1)) && (e->capacity > e->flow))
			{
				L[e->v] = L[curr] + 1;
				Q.push(e->v);
			}
		}
	}
	
	return (L[n] != INF);
}
 
edgestack path;
bool Augment(int node)
{	
	if (node == n)
	{
		int mi = INF;
		for (edgestacknode* it = path.top; it != nullptr; it = it->prev)
		{
			mi = min(mi, it->e->capacity - it->e->flow);
		}
		
		for (edgestacknode* it = path.top; it != nullptr; it = it->prev)
		{
			it->e->flow          += mi;
			it->e->reverse->flow -= mi;
		}
		
		maxFlow += mi;
		
		return true;
	}
	
	bool res = false;
	for (edge* e : G[node])
	{	
		if (E[e->v] && (L[e->v] == (L[node] + 1)) && (e->capacity > e->flow))
		{
			path.Push(new edgestacknode(e));
			bool res_neigh = Augment(e->v);
			path.Pop();
			
			if (!res_neigh)
			{
				E[e->v] = false;
			}
			else
			{
				res = true;
			}
		}
	}
	
	return res;
}