Cod sursa(job #718842)

Utilizator AndreiRSStatescu Andrei Rares AndreiRS Data 21 martie 2012 10:15:08
Problema Flux maxim de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.74 kb
#include <stdio.h>
#include <vector>
#include <queue>
#include <assert.h>
using namespace std;

const int nmax = 355, OO = (1<<31)-1;
int N, M, S, D;
int viz[nmax], inq[nmax], T[nmax], dst[nmax];
int C[nmax][nmax], F[nmax][nmax], P[nmax][nmax];

vector <int> V[nmax];
queue <int> Q;

void cit ()
{
	scanf ("%d%d%d%d", &N, &M, &S, &D);
	for (int i = 1, x, y, c, p; i <= M; i++)
	{
		scanf ("%d%d%d%d", &x, &y, &c, &p);
		
		V[x].push_back (y);
		V[y].push_back (x);
		
		C[x][y] = c;
		C[y][x] = -c;
		P[x][y] = P[y][x] = p;
	}
}

int bellford ()
{
	int n, f, p, i;
	for (i = 1; i <= N; i++)
	{
		viz[i] = 0;
		inq[i] = 0;
		dst[i] = 0;
		T[i] = 0;
	}
	Q.push (S);
	T[S] = 0;
	viz[S] = 1;
	inq[S] = 1;
	
	while ( !Q.empty () )
	{
		n = Q.front ();
		Q.pop ();
		inq[n] = 0;
		
		for (i = 0; i < V[n].size(); i++)
		{
			f = V[n][i];
			p = P[n][f];
			if (dst[f] > dst[n] + p && C[n][f] > F[n][f])
			{
				dst[f] = dst[n] + p;
				T[f] = n;
				if (inq[f] == 0)
				{
					Q.push (f);
					viz[f] ++;
					inq[f] = 1;
					if (viz[f] == N)
						assert (0);
				}
			}
		}
	}
	
	return viz[D];
}

void flux ()
{
	int n, m;
	
	while (bellford ())
	{
		m = OO;
		for (n = N; T[n] != 0; n = T[n])
		{
			m = min (m, C[T[n]][n] - F[T[n]][n]);
		}
		
		for (n = N; T[n] != 0; n = T[n])
		{
			F[T[n]][n] += m;
			F[n][T[n]] -= m;
		}
	}
}

void afi ()
{
	int i, j;
	long long c = 0;
	for (i = 1; i <= N; i++)
	{
		for (j = 1; j <= N; j++)
		{
			if (F[i][j] > 0)
			{
				c += F[i][j] * P[i][j];
			}			
		}
	}
	printf ("%lld\n", c);
}

int main ()
{
	freopen ("fmcm.in", "r", stdin);
	freopen ("fmcm.out", "w", stdout);
	
	cit ();
	flux ();
	afi ();
	
	return 0;
}