Cod sursa(job #703875)

Utilizator mottyMatei-Dan Epure motty Data 2 martie 2012 15:07:03
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.86 kb
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <queue>

using namespace std;

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

const int N = 353;
const int INF = 0x3f3f3f;

int n;			// Number of nodes
int s;			// Source
int d;			// Destination
int fat[N];		// fat[i] - Father of node i in the current road
int best[N];	// best[i] - Best price to get from s to i on the unsat. edges
int vis[N];		// vis[i] - How many times was i visited in this call
int f[N][N];	// f[i][j] - Flow sent through edge i, j
int c[N][N];	// c[i][j] - Capacity of edge i, j
int p[N][N];	// p[i][j] - Price of edge i, j

void Read()
{
	int m;
	in >> n >> m >> s >> d;

	while (m--)
	{
		int a, b, pr, cap;
		in >> a >> b >> cap >> pr;

		c[a][b] = cap;
		p[a][b] = pr;
		p[b][a] = -pr;
	}
}

bool Road()
{
	queue <int> q;
	memset(vis, 0, sizeof(vis));
	memset(best, INF, sizeof(best));

	q.push(s);
	vis[s] = 1;
	best[s] = 0;

	while (!q.empty())
	{
		int node = q.front();

		for (int i = 1; i <= n; ++i)
			if (c[node][i] - f[node][i] > 0
				&& best[node] + p[node][i] < best[i])
			{
				best[i] = best[node] + p[node][i];
				fat[i] = node;
				++vis[i];

				if (vis[node] == n)
					return vis[d];

				q.push(i);
			}

		q.pop();
	}

	return vis[d];
}

int PriceMaxFlow()
{
	int totalPrice = 0;

	while (Road())
	{
		int node = d;
		int minFlow = INF;

		while (node != s)
		{
			if (c[fat[node]][node] - f[fat[node]][node] < minFlow)
				minFlow = c[fat[node]][node] - f[fat[node]][node];

			node = fat[node];
		}

		node = d;

		while (node != s)
		{
			f[fat[node]][node] += minFlow;
			f[node][fat[node]] -= minFlow;

			totalPrice += minFlow * p[fat[node]][node];

			node = fat[node];
		}
	}

	return totalPrice;
}

int main()
{
	Read();
	out << PriceMaxFlow() << "\n";

	return 0;
}