Cod sursa(job #489508)

Utilizator ilincaSorescu Ilinca ilinca Data 2 octombrie 2010 19:57:20
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.09 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>

#define nmax 355
#define inf (1<<31)-1

using namespace std;

int n, m, s, d, cost [nmax] [nmax], cap [nmax] [nmax], f [nmax] [nmax], p [nmax];
int D [nmax], D2 [nmax];
vector <int> g [nmax];
vector <bool> inq (nmax);
priority_queue <int, vector <int>, greater <int> > q;


void bellman_ford ()
{
	queue <int> q;
	int i, k;
	for (i=1; i <= n; ++i) D [i]=inf;
	D [s]=0;
	inq [s]=true;
	q.push (s);
	while (!q.empty ())
	{
		k=q.front ();
		q.pop ();
		inq [s]=false;
		for (i=0; i != g [k].size (); ++i)
		{
			if (cap [k] [g [k] [i]] == 0) continue;
			if (D [g [k] [i]] <= D [k]+cost [k] [g [k] [i]]) continue;
			D [g [k] [i]]=D [k]+cost [k] [g [k] [i]];
			if (!inq [g [k] [i]])
			{
				inq [g [k] [i]]=true;
				q.push (g [k] [i]);
			}
		}
	}
}

bool dijkstra ()
{
	int i, k;
	int C;
	for (i=1; i <= n; ++i) inq [i]=false, D2 [i]=inf;
	q.push (s);
	D2 [s]=0;
	inq [s]=true;
	while (!q.empty ())
	{
		k=q.top ();
		q.pop ();
		inq [k]=false;
		for (i=0; i != g [k].size (); ++i)
		{
			if (cap [k] [g [k] [i]] == f [k] [g [k] [i]]) continue;
			C=(int)D [k]-D [g [k] [i]]+cost [k] [g [k] [i]];
			if (D2 [g [k] [i]] <= D2 [k]+C) continue;
			D2 [g [k] [i]]=D2 [k]+C;
			if (!inq [g [k] [i]])
			{
				inq [g [k] [i]]=true;
				q.push (g [k] [i]);
			}
			p [g [k] [i]]=k;
		}
	}
	return D2 [d] != inf;
}

int flux ()
{
	int i;
	int min, C=0;
	while (dijkstra ())
	{
		min=inf;
		for (i=d; i != s; i=p [i]) if (min > cap [p [i]] [i]-f [p [i]] [i]) min=cap [p [i]] [i]-f [p [i]] [i];
		for (i=d; i != s; i=p [i])
		{
			f [p [i]] [i]+=min;
			f [i] [p [i]]-=min;
		}
		C += (D2 [d]+D [d])*min;
//		memcpy (D, D2, sizeof (D));
	}
	return C;
}

int main ()
{
	freopen ("fmcm.in", "r", stdin);
	freopen ("fmcm.out", "w", stdout);
	int i, x, y, c, z;
	scanf ("%d%d%d%d", &n, &m, &s, &d);
	for (i=1; i <= m; ++i)
	{
		scanf ("%d%d%d%d", &x, &y, &c, &z);
		cap [x] [y]=c;
		cost [x] [y]=z;
		cost [y] [x]=-z;
		g [x].push_back (y);
		g [y].push_back (x);
	}
	bellman_ford ();
//	for (i=1; i <= n; ++i) fprintf (stderr, "%d ", D [i]);
	printf ("%d\n", flux ());
	return 0;
}