Cod sursa(job #479647)

Utilizator razvi9Jurca Razvan razvi9 Data 24 august 2010 17:48:39
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.2 kb
#include <fstream>
#include <queue>
#include <bitset>
#include <vector>
using namespace std;
typedef unsigned int uint;

const int INF = 0x7f7f7f7f;
const int N = 360;
int n, S, D;
int F[N][N], C[N][N], cost[N][N], dist[N], last[N];
vector<vector<int> > a;
long long sum = 0;

void bellman()
{
	queue<int> q;
	bitset<400> used;

	memset(dist, 0x7f, sizeof(dist));
	q.push(S);
	dist[S] = 0;
	int v;
	while(!q.empty())
	{
		v = q.front(); q.pop(); used[v] = false;
		for(vector<int>::iterator it = a[v].begin(); it != a[v].end(); ++ it)
			if (C[v][*it] && dist[*it] > dist[v] + cost[v][*it])
			{
				dist[*it] = dist[v] + cost[v][*it];
				if (!used[*it])
					q.push(*it),
					used[*it] = true;
			}
	}
}

priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > H;

bool dijkstra()
{
	for(int i=1;i<=n;++i)
		for(vector<int>::iterator it = a[i].begin(); it!=a[i].end(); ++it)
			if(dist[i] != INF && dist[*it] != INF)
				cost[i][*it] += dist[i] - dist[*it];

	memset(dist, 0x7f, sizeof(dist));
	dist[S] = 0;
	H.push(make_pair(0, S));

	while(!H.empty())
	{
		int v = H.top().second, d = H.top().first; H.pop();

		if (d != dist[v])
			continue;

		for (vector<int>::iterator it = a[v].begin(); it != a[v].end(); ++ it)
			if (C[v][*it] - F[v][*it] > 0 && dist[*it] > dist[v] + cost[v][*it])
				dist[*it] = dist[v] + cost[v][*it],
				last[*it] = v,
				H.push(make_pair(dist[*it], *it));
	}

	return dist[D] != INF;
}

long long flux()
{
	long long res = 0;

	long long sum = dist[D];
	while (dijkstra())
	{
		int Fmin = INF;
		for (int v = D; v != S; v = last[v])
			Fmin = min(Fmin, C[last[v]][v] - F[last[v]][v]);
		
		for (int v = D; v != S; v = last[v])
			F[last[v]][v] += Fmin,
			F[v][last[v]] -= Fmin;

		sum += dist[D];
		res += sum * Fmin;
	}

	return res;
}

int main()
{
	ifstream cin("fmcm.in");
	ofstream cout("fmcm.out");

	int m, x, y, cap, cst;
	cin >> n >> m >> S >> D;
	a.resize(n+1);
	while(m--)
	{
		cin >> x >> y >> cap >> cst;
		C[x][y] = cap;
		cost[x][y] = cst;
		cost[y][x] = -cst;
		a[x].push_back(y);
		a[y].push_back(x);
	}

	bellman();

	cout << flux() << endl;

	return 0;
}