Cod sursa(job #474908)

Utilizator tamas_iuliaTamas Iulia tamas_iulia Data 5 august 2010 15:26:42
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 2.62 kb
#include <stdio.h>
#include <vector>
#include <queue>
#define Nmax 355
#define pb push_back
#define INF 2147000000
using namespace std;

queue< int > Q; int inq[Nmax];
vector< int > v[Nmax];
int F[Nmax][Nmax],C[Nmax][Nmax],Cost[Nmax][Nmax];
int H[Nmax],Dist[Nmax],poz[Nmax],prev[Nmax];
int n,m,S,D,dh;
int Sum,rez,ok;

inline void swap(int i,int j){
	int aux=H[i]; H[i]=H[j]; H[j]=aux;
	poz[H[i]]=i; 
	poz[H[j]]=j;
}

inline void Up(int k){
	int tata=k/2;
	while( tata && Dist[H[tata]] > Dist[H[k]] ){
		swap(tata,k);
		k=tata; tata=k/2;
	}
	
}

inline void Down(int k){
	int l,r,min,ok=1;
	while( ok ){
		ok=0;
		l=k*2; r=l+1; min=k;
		if( l<=dh && Dist[H[l]] < Dist[H[min]] ) min=l;
		if( l<=dh && Dist[H[r]] < Dist[H[min]] ) min=r;
		if( min != k){
			ok=1;
			swap(k,min);
			k=min;
		}
	}
}		

void bellman_ford(){
	int f,i;
	vector< int >:: iterator it;
	
	for(i=1;i<=n;++i) Dist[i]=INF;
	Dist[S]=0;
	Q.push(S);
	
	while( !Q.empty() ){
		f=Q.front();
		Q.pop(); inq[f]=0;
		if( f == D ) continue;
		
		for(it=v[f].begin(); it!=v[f].end(); ++it)
			if( C[f][*it] > F[f][*it] && Dist[*it] > Dist[f]+Cost[f][*it] ){
				Dist[*it] = Dist[f]+Cost[f][*it];
				if( ! inq[*it] ){
					inq[*it]=1;
					Q.push(*it);
				}
			}
	}
	Sum=Dist[D];
}

void solve(){
	int i,fmin,pmin; vector< int >:: iterator it;
	
	for(i=1;i<=n;++i)
		if( Dist[i] != INF )
		for(it=v[i].begin(); it!=v[i].end(); ++it)
			if( Dist[*it] != INF ) Cost[i][*it] += Dist[i] - Dist[*it];

	for(i=1;i<=n;++i) Dist[i]=INF, H[i]=i, poz[i]=i, prev[i]=-1;
	dh=n; Dist[S]=0;
	
	Up(S);
	while( dh && Dist[H[1]] != INF ){
		pmin=H[1];
		swap(1,dh); dh--;
		Down(1);

		for(it=v[pmin].begin(); it!=v[pmin].end(); ++it)
			if( C[pmin][*it] > F[pmin][*it] && Dist[*it] > Dist[pmin]+Cost[pmin][*it]){
				Dist[*it] = Dist[pmin]+Cost[pmin][*it];
				Up(poz[*it]);
				prev[*it]=pmin;
			}
	
	}
	
	if( Dist[D] != INF ){
		fmin=INF;
		
		for(i=D; i!=S; i=prev[i])
			fmin=fmin < C[prev[i]][i] - F[prev[i]][i] ? fmin : C[prev[i]][i] -F[prev[i]][i];
		
		for(i=D; i!=S; i=prev[i]){
			F[prev[i]][i] += fmin;
			F[i][prev[i]] -= fmin;
		}
		
		Sum += Dist[D];
		rez += Sum * fmin;
		ok=1;
	}
}

int main(){
	int i,x,y;
	freopen("fmcm.in","r",stdin);
	freopen("fmcm.out","w",stdout);
	scanf("%d%d%d%d",&n,&m,&S,&D);
	for(i=1;i<=m;++i){
		scanf("%d%d",&x,&y);
		scanf("%d%d",&C[x][y],&Cost[x][y]);
		C[y][x]=0; Cost[y][x]=-Cost[x][y];
		v[x].pb(y);
		v[y].pb(x);
	}
	
	bellman_ford();
	
	ok=1;
	while( ok ){
		ok=0;
		solve();
	}
	
	printf("%d\n",rez);
	fclose(stdin); fclose(stdout);
	return 0;
}