Cod sursa(job #489968)

Utilizator ilincaSorescu Ilinca ilinca Data 4 octombrie 2010 12:21:53
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.27 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

#define nmax 375
#define inf 1<<29
#define ff first
#define ss second

using namespace std;

typedef pair <short, short> ii;

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

ifstream fi("fmcm.in");
ofstream fo("fmcm.out");

void bellman_ford ()
{
	queue <short> q;
	short 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 ()
{
	short i, k, x;
	ii nod;
	int C;
	for (i=1; i <= n; ++i) D2 [i]=inf;
	q.push (ii (0, s));
	D2 [s]=0;
	while (!q.empty ())
	{
		nod=q.top ();
		k=nod.ss;
		x=nod.ff;
		q.pop ();
		if (x > D2 [k]) continue;
		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]] <= x+C) continue;
			D2 [g [k] [i]]=x+C;
			q.push (ii (D2 [g [k] [i]], g [k] [i]));
			p [g [k] [i]]=k;
		}
	}
	return D2 [d] != inf;
}

int flux ()
{
	short 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);
	short i, x, y, c, z;
	fi>>n>>m>>s>>d;
	//scanf ("%hd%hd%hd%hd", &n, &m, &s, &d);
	for (i=1; i <= m; ++i)
	{
	//	scanf ("%hd%hd%hd%hd", &x, &y, &c, &z);
		fi>>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 ());
	fo<<flux();
	return 0;
}