Cod sursa(job #777231)

Utilizator danalex97Dan H Alexandru danalex97 Data 11 august 2012 15:54:58
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.1 kb
// Problema fluxului maxim de cost minim este o problema a
// categoriei fluxului si functioneaza pe acelasi principiu.
// O vom rezolva in acelasi fel cu moduficarea ca folosim un 
// algoritm de determinare a drumului de cost minim.
// Cel mai convenabil din punct de vedere implementare/eficienta este
// Bellman-Ford. Complexitatea teoretica este O(N*N*M*M). 
// Complexitatea este supraestimata , iar complexitatea optima este cea
// a algoritmului lui Dijkstra: O(N*M*M*lg N).

#include <fstream>
#include <vector>
#include <cstring>
#include <queue>

using namespace std;

const int Nmax = 355;
const int Mmax = 12511;
const int oo = 1<<30;

int Flux[Nmax][Nmax];
int Cost[Nmax][Nmax];

vector< int > Leg[Nmax];
queue< int > Q;

int N,M,Start,End;
int Rez,Drum;

int Dist[Nmax],Dad[Nmax],Used[Nmax];

ifstream F("fmcm.in");
ofstream G("fmcm.out");

int Bellman()
{
	for (int i=1;i<=N;++i)
	{
		Dad[i]=-1;
		Dist[i]=oo;
	}
	
	Dist[Start] = 0;
	Q.push( Start );
	memset(Used, 0, sizeof(Used));
	Used[Start] = 1;
	
	while ( Q.size() )
	{
		int i = Q.front();
		
		for (int j=0;j<int( Leg[i].size() );++j)
			if ( Flux[i][Leg[i][j]] > 0 && Dist[i] + Cost[i][Leg[i][j]] < Dist[Leg[i][j]] )
				{
					Dist[ Leg[i][j] ] = Dist[i] + Cost[i][ Leg[i][j] ];
					Dad[ Leg[i][j] ] = i;
					
					if ( !Used[ Leg[i][j] ] ) 
					{
						Q.push( Leg[i][j] );
						Used[ Q.back() ] = 1;
					}
				}
			
		Q.pop();
		Used[i]=0;
	}
	
	if ( Dist[End] != oo ) 
	{
		int Vmin = oo;
		Drum = 1;
		
		for (int i = End; i != Start; i = Dad[i]) 
			Vmin = min(Vmin, Flux[Dad[i]][i] );
		
		for (int i = End; i != Start; i = Dad[i])
		{
			Flux[Dad[i]][i] -= Vmin;
			Flux[i][Dad[i]] += Vmin;
		}
		
		return Vmin * Dist[End];
	}

	return 0;
}

int main()
{
	F>>N>>M>>Start>>End;
	for (int i=1;i<=M;++i)
	{
		int x,y,cap,cos;
		F>>x>>y>>cap>>cos;
		
		Flux[x][y]=cap;
		Cost[x][y]=cos;
		Cost[y][x]=-cos;
		
		Leg[x].push_back( y );
		Leg[y].push_back( x );
	}
	
	Rez=0;
	Drum=1;
	
	while ( Drum )
	{
		Drum=0;
		Rez+=Bellman();
	}
	
	G<<Rez<<'\n';
}