Cod sursa(job #811658)

Utilizator MtkMarianHagrSnaf MtkMarian Data 12 noiembrie 2012 19:47:41
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.5 kb
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include <string.h>
using namespace std;


#define NMAX 355
#define INF 2e7




int n , m , x ,y , z ,fluxmin,cp,surs,dest ,global ,k=0,sum;

long long flx ;

vector< int > g[NMAX] ;
vector< int > hp ;


int d[NMAX] , h[NMAX] , poz[NMAX] ;
int c[NMAX][NMAX]={0} , viz[NMAX] , t[NMAX] ;
int flux[NMAX][NMAX] ={0} , cost[NMAX][NMAX] ;

void bellford()
{
	
	
	for(int i = 1 ; i <= n ; ++i)
	{		
		d[i]=INF;
		
	}

	memset(viz, 0, sizeof(viz));

	long pas=0 ;
	d[surs] = 0;
	hp.clear();
	hp.push_back(surs);
	make_heap(hp.begin(),hp.end());
	viz[surs]=1;

	while(hp.size() && pas<=1LL*n*m)		
	{
		pop_heap(hp.begin(),hp.end() ) ;
		
		int el = hp.back();

		
		hp.pop_back();

		viz[el]=0;

		++pas;

		for(int j=0 ; j < g[el].size() ; ++j)
		{
			int y1=g[el][j];

			z=cost[el][y1];

			if( d[ y1 ] > d[ el ] + z && flux[el][y1]<c[el][y1]  )			
			{
				d[ y1 ] = d[ el ]+z;
				if( !viz[y1] )
				{
					viz[y1]=1;
					hp.push_back(y1);
					push_heap(hp.begin(),hp.end());
				}
			}
		}
	}
	sum=d[dest];
	
}


void swap(int x,int y)
{
	int t=h[x];
	h[x]=h[y];
	h[y]=t;
}

void upheap(int ln)
{
	int f;
	while( ln>1 )
	{
		f = ln >> 1;
		if(d[ h [ f] ] > d[ h [ ln ] ])
		{
			poz[h[ln]]=f;
			poz[h[f]]=ln;
			swap( f , ln );
			ln=f;
		}
		else ln=1;
	}


}
void downheap(int w)
{
	
	int f;
	
	while(w <= k)
	{
		f = w;
		if( ( w << 1 ) <= k )
		{
			f=w<<1;
			if(f+1 <= k)
				if( d[ h[f+1] ]<d[h[f]]) ++f; 
		}
		else
			return;
		if(d[h[w]]>d[h[f]])		
		{
			poz[h[w]]=f;

			poz[h[f]]=w;

			swap(w,f);

			w=f;
		}
		else return;
	
	}
}


int djheap()
{
  for(int i = 1 ; i <= n ; ++i)
	{
		
		for(int j = 0 ; j < g[i].size() ; j++)
		{
			y = g[i][j];
			if( d[i]!=INF && d[y]!=INF)
					cost[i][y] += d[i] -d[y];
		}

	}
  
	
	for(int i=1;i<=n;++i)
	{
		d[i]=INF;
		poz[i]=-1;
		t[i]=-1 ;
	}

		k = 0;

		d[surs] = 0;

		poz[ surs ] = 1;

		h[ ++k ] = surs;

		

			while( k )
			{
		
				
				int x=h[1]; 
				swap(1,k);
				poz[h[1]]=1;
				 --k ;
				downheap( 1 );			

				for(int i=0 ; i<g[x].size() ;++i )
				{
			
					int y=g[x][i];

					if(d[y]>d[x]+cost[x][y] && flux[x][y]<c[x][y]) 
					{
				
						d[y]=d[x]+cost[x][y];
						t[y] = x;
						if( poz[y] != -1 )								
							upheap(poz[y]);						
						else
							{

								h[++k]=y;	
								poz[h[k]]=k;
								upheap(k);
							}
					}
				
				}

			}
			
			
	if( d[ dest ] != INF)
	{
		fluxmin=INF;
		global=1;

		for(int nod = dest ; nod != surs ; nod = t[nod])
			fluxmin =  min ( fluxmin , c[ t [ nod ] ] [ nod ] - flux [ t[nod] ] [ nod ] ) ;				

		 for(int nod = dest ; nod != surs; nod = t [ nod ] )
			{
				flux [ t[ nod ] ][nod] += fluxmin;
				flux [nod] [ t[nod] ] -= fluxmin;
			}
			sum+=d[dest];
			return sum*fluxmin ;
	}

	return 0 ;



			
}

void apel ()
{
	global=1;

	while( global )
	{
		global = 0;
		flx += djheap();
	}
}

void citeste()
{
	scanf("%d %d %d %d" , &n , &m , &surs , &dest );

	for(int i = 1 ; i <= m ;++i)
	{
		scanf("%d %d %d %d",&x,&y,&cp,&z);

		c[x][y] = cp;

		cost[x][y] +=z ;
		cost[y][x] -=z ;

		g[x].push_back ( y );
		g[y].push_back( x );
	}
	

}

int main()
{
	freopen("fmcm.in", "r",stdin);
	freopen("fmcm.out","w",stdout);	
	citeste();	
	
	bellford();
	
	
	apel();
	
	printf("%lld",flx);

	return 0;
}