Cod sursa(job #2696387)

Utilizator madalin_frFrincu Madalin madalin_fr Data 15 ianuarie 2021 19:44:51
Problema Flux maxim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.92 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <set>
#define inf 100006
using namespace std;
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
int i,j,n,s,t,m;
vector<int> tata;
vector<int> viz;
queue<int> coada;

struct arc
{
	int x;
	int y;
	int cp;
	int flx;
};

vector<arc> arce;




int calc_flux_plus(int nod) // flux care iese din nod
{
	int flux = 0;
	for(i=1;i<=m;i++)
	{
		if(arce[i].x == nod)
		{
			flux += arce[i].flx;
		}
	}
	return flux;
}


int calc_flux_minus(int nod) // flux care intra in nod
{
	int flux = 0;
	for(i=1;i<=m;i++)
	{
		if(arce[i].y == nod)
		{
			flux += arce[i].flx;
		}
	}
	return flux;
}




bool construieste_s_t_lant_nesat_BF()
{

	coada = queue<int>();	// gol
	coada.push(s);
	viz[s] = 1;
	while(!coada.empty())
	{
		i = coada.front();
		coada.pop();
		for(int k=1;k<=m;k++) 	// arc direct
		{
			if(arce[k].x == i)
			{
				j = arce[k].y;
				if(viz[j] == 0 && arce[k].cp - arce[k].flx > 0)
				{
					coada.push(j);
					viz[j] = 1;
					tata[j] = i;
					if(j==t)
						return true;
				}
			}
		}
		for(int k=1;k<=m;k++)	// arc invers
		{
			if(arce[k].y == i)
			{
				int j = arce[k].x;
				if(viz[j] == 0 && arce[k].flx > 0)
				{
					coada.push(j);
					viz[j] = 1;
					tata[j] = -i;
					if(j==t)
						return true;
				}
			}
		}
	}
	return false;
}


void revizuieste_flux_lant()
{
	i = t;
	int minim = inf;
	// calculam capacitatea reziduala minima
	while(i != s)
	{
		if(tata[i] < 0)
		{
			for(int k=1;k<=m;k++)
			{
				if(arce[k].x == i && arce[k].y == -1 * tata[i])
					if(arce[k].flx < minim)
					{
						minim = arce[k].flx;
						break;
					}
			}
			i = tata[i] * (-1);
		}
		else
		{
			for(int k=1;k<=m;k++)
			{
				if(arce[k].x == tata[i] && arce[k].y == i)
					if(arce[k].cp - arce[k].flx < minim)
					{
						minim = arce[k].cp - arce[k].flx;
						break;
					}
			}
			i = tata[i];
		}
	}
	//revizuim fluxul din lantul s-t curent
	i = t;

	while(i != s)
	{
		if(tata[i] < 0)
		{
			for(int k=1;k<=m;k++)
			{
				if(arce[k].x == i && arce[k].y == -1 * tata[i])
				{
					arce[k].flx -= minim;
					break;
				}
			}
			i = tata[i] * (-1);
		}
		else
		{
			for(int k=1;k<=m;k++)
			{
				if(arce[k].x == tata[i] && arce[k].y == i)
				{
					arce[k].flx += minim;
					break;
				}
			}
			i = tata[i];
		}
	}

}

void afiseaza_flux()
{
	int flux_maxim = 0;
	for(int k=1;k<=m;k++)
	{
		if(arce[k].x == s)
			flux_maxim += arce[k].flx;
	}
	fout << flux_maxim << endl;
}




int main()
{
	fin >> n;
	fin >> m;
	arce.resize(m+1);
	tata.resize(n+1);
	viz.resize(n+1);
	for(i=1;i<=m;i++)
	{
		fin >> arce[i].x >> arce[i].y >> arce[i].cp;
		arce[i].flx = 0;
	}
	s = 1;
	t = n;

	while(construieste_s_t_lant_nesat_BF())
        revizuieste_flux_lant();
	afiseaza_flux();

}