Cod sursa(job #644252)

Utilizator balakraz94abcd efgh balakraz94 Data 5 decembrie 2011 22:16:13
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.29 kb
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#define infile "fmcm.in"
#define outfile "fmcm.out"
#define n_max 355
#define INF 1<<30
#define pb push_back
#define mkp make_pair
#define FOR(g) \
   for(vector<int> ::iterator it = g.begin(); it!=g.end(); ++it)
using namespace std;


vector < int > v[n_max];

int Cost[n_max][n_max], C[n_max][n_max], F[n_max][n_max], Dist[n_max], T[n_max];

int N, M, S, D;

int Drum, Sum;



void citeste()
{
	freopen(infile,"r",stdin);
	
	scanf("%d %d %d %d", &N, &M, &S, &D);
	
	int x, y, c, cost;
	
	while(M--)
	{
		scanf("%d %d %d %d", &x, &y, &c, &cost);
		
		v[x].pb(y);
		v[y].pb(x);
		
		Cost[x][y] = cost;
		Cost[y][x] = -cost;
		C[x][y] = c;
		
	}
	
	fclose(stdin);
}



void BellmanFord()
{
	for (int i = 1; i <= N; i++) 
		Dist[i] = INF;
	Dist[S] = 0;
	
	int ok = 0;
	
	for(int i=1; i<=N && !ok; i++)
	{
		for(int j=1;j<=N;j++)
			FOR(v[j])
				if(C[j][*it] - F[j][*it] > 0 && Dist[j] + Cost[j][*it] < Dist[*it] )
					Dist[*it] = Dist[j] + Cost[j][*it], ok=0;
	}	

	Sum = Dist[D];
}



int Dijkstra()
{
	for(int i=1; i<=N; i++)
		FOR(v[i])
			if(Dist[i]!=INF && Dist[*it]!=INF)
				Cost[i][*it] += Dist[i] - Dist[*it];


	priority_queue < pair <int, int> > H;		

	for(int i=1;i<=N;i++)
	{
		Dist[i] = INF;
		T[i] = 0;
	}		
	Dist[S] = 0;
	
	H.push(mkp(-0,S));
	
	while(!H.empty())
	{
		int nodc = H.top().second;
		H.pop();
		
		FOR(v[nodc])
			if(C[nodc][*it] - F[nodc][*it] > 0 && Dist[nodc] + Cost[nodc][*it] < Dist[*it])
			{
				Dist[*it] = Dist[nodc] + Cost[nodc][*it];
				H.push(mkp(-Dist[*it], *it));
				T[*it] = nodc;
			}
	}
	
	if(Dist[D] == INF)
		return 0 ;
	
	Drum = 1;
	int fmin = INF;
	
	for(int i = D; i != S; i = T[i])
		fmin = min(fmin, C[T[i]][i] - F[T[i]][i]);
	
	for(int i = D; i != S; i = T[i])
	{
		F[T[i]][i] += fmin;
		F[i][T[i]] -= fmin;
	}
	
	Sum += Dist[D];
	
	return Sum * fmin;
}




long long Flux()
{
	long long sol = 0;
	Drum = 1;
	
	while(Drum)
	{
		Drum = 0;
		sol += Dijkstra();
	}
	
	return sol;
}



void afiseaza()
{
	freopen(outfile,"w",stdout);
	
	printf("%lld\n",Flux());
	
	fclose(stdout);
}


int main()
{
	citeste();
	
	BellmanFord();
	
	afiseaza();
	
	return 0;
}