Cod sursa(job #413076)

Utilizator BaduBadu Badu Badu Data 7 martie 2010 16:53:53
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.25 kb
#include<fstream>
#include<vector>
#include<queue>
#include<algorithm>
#include<cstdio>


const int maxx = 360;
const int inf = 0x3f3f3f3f;
const int MAXS = 10000;

using namespace std;

vector < pair <short int, short int> > G[maxx];
vector <short int> T(maxx,0);
vector <bool> Viz;
vector <int> dist;
short int C[maxx][maxx];
short int F[maxx][maxx];
char s[ MAXS ];
short int n,m,S,D,cnt;

inline int min( int a, int b) { return ( a<b?a:b ); }

struct cmp {
	
	bool operator() (const short int &a, const short int &b) const
	{
		
		return dist[a] > dist[b];
	}
};
priority_queue< short, vector< short int > , cmp > Q;

bool Dijkstra(){

	Viz.clear();
	Viz.resize(maxx, false);
	dist.clear();
	dist.resize(maxx,inf);
	
	Q.push(S);
	dist[S]=0;
	Viz[S]=true;
	T[S]=1;
	
	while( !Q.empty() ){
		
		short int nod = Q.top();
		Q.pop();
		Viz[nod] = 0;
		
		vector< pair<short int,short int> >::iterator it;
		for( it = G[nod].begin(); it!=G[nod].end(); it++){
			
			if( C[nod][it->first] <= F[nod][it->first] || dist[it->first] <= dist[nod] + it->second ) continue;
			
			dist[ it->first ] = dist[nod] + it->second;
			T[it->first] = nod;
			
			if(Viz[it->first]) continue;
			
			Viz[it->first]=1;
	
			Q.push(it->first);
		}
	}
	return ( dist[D] < inf );
}

void Read( int& x )
{
	int sgn = 1;
	
	while( !isdigit( s[cnt] ) )
	{
		if( s[cnt] == '-' ) sgn = -1;
		if( ++cnt == MAXS )
		{
			fread( s, 1, MAXS, stdin );
			cnt = 0;
		}
	}
	
	x = 0;
	
	while( isdigit( s[cnt] ) )
	{
		x = x * 10 + s[cnt] - '0';
		if( ++cnt == MAXS )
		{
			fread( s, 1, MAXS, stdin);
			cnt = 0;
		}
	}
	
	x *= sgn;
}

int main(){
	
	//ifstream f("fmcm.in");
	//ofstream g("fmcm.out");
	
	freopen("fmcm.in","r",stdin);
	freopen("fmcm.out","w",stdout);
	
	//f>>n>>m>>S>>D;
	scanf("%hd%hd%hd%hd",&n,&m,&S,&D);
	int x,y,c,z;
	while( m-- ) { 
		
		//f>>x>>y>>c>>z;
		Read(x);
		Read(y);
		Read(c);
		Read(z);
		C[x][y]=c;
		G[x].push_back( make_pair( y,z) );
		G[y].push_back( make_pair( x,-z));
	}
	
	int flow=0,Rez=0;
	
	while( Dijkstra() ){
			short int t;flow=inf;
			for( t=D; t!=S; t=T[t] ) flow = min( flow, C[T[t]][t]-F[T[t]][t] );
			for( t=D; t!=S; t=T[t] ){ F[T[t]][t]+=flow; F[t][T[t]]-=flow; }
			
			Rez += dist[D] * flow;
	}
	
	//g<<Rez;
	printf("%d\n",Rez);
	
return 0;
}