Cod sursa(job #470545)

Utilizator ooctavTuchila Octavian ooctav Data 14 iulie 2010 15:36:35
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.52 kb
#include<cstdio>
#include<set>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;

const int INF = 1<<30;
const int NMAX = 355;
const int MMAX = 12505;

int N, M, S, D;
int REZ;
int FLUX;
int tata[NMAX];
vector<int> G[NMAX];
int C[NMAX][NMAX];
int F[NMAX][NMAX];
int s[NMAX][NMAX];
int DRUM;
int d[NMAX];

struct cmp
{
	bool operator()(const int &a, const int &b) const
	{
		return d[a] > d[b];
	}
};

void write()
{
	for(int i = 1 ; i <= N ; i++)
	{
		for(int j = 1 ; j <= N ; j++)
			printf("%d ", s[i][j]);
		printf("\n");
	}
	printf("\n\n\n");
}

void citi()
{
	int x, y, cap, cost;
	scanf("%d%d%d%d", &N, &M, &S, &D);
	for(int i = 1 ; i <= M ; i++)
	{
		scanf("%d%d%d%d", &x, &y, &cap, &cost);
		G[x].push_back(y);
		G[y].push_back(x);
		C[x][y] = cap;
		s[x][y] = cost;
		s[y][x] = -cost;
	}
}

int bellmanford()
{
	queue<int> Q;
	int f;
	Q.push(S);
	fill(d + 1, d + N + 1, INF);
	d[S] = 0;
	while(!Q.empty())
	{
		f = Q.front();
		Q.pop();
		for(vector<int> :: iterator it = G[f].begin() ; it != G[f].end() ; it++)
			if(d[f] + s[f][*it] < d[*it] && F[f][*it] < C[f][*it])
			{
				d[*it] = d[f] + s[f][*it];
				Q.push(*it);
			}
	}
	
	return d[D];
}

void muchii()
{
	for(int i = 1 ; i <= N ; i++)
		for(int j = 0 ; j < (int)G[i].size() ; j++)
			if(d[i] != INF && d[G[i][j]] != INF)
				s[i][G[i][j]] += d[i] - d[G[i][j]];
}

bool dijkstra()
{
	priority_queue<int, vector<int>, cmp > Q;
	bool viz[NMAX] = {0};
	//bool succes = 0;
	
	fill(d + 1, d + N + 1, INF);
	/*//*/fill(tata + 1, tata + N + 1, INF);
	d[S] = 0;
	viz[S] = 1;
	
	Q.push(S);
	while(!Q.empty())
	{
		int nod = Q.top();
		Q.pop();
		//viz[nod] = 0;
		for(vector<int> :: iterator it = G[nod].begin() ; it != G[nod].end() ; it++)
			if(d[nod] + s[nod][*it] < d[*it] && F[nod][*it] < C[nod][*it])
			{
				d[*it] = d[nod] + s[nod][*it];
				tata[*it] = nod;
				
				//if(viz[*it])	continue;
				
				Q.push(*it);
				viz[*it] = 1;

			}
	}
	
	return d[D] < INF;
}

int main()
{
	freopen("fmcm.in", "r", stdin);
	freopen("fmcm.out", "w", stdout);
	citi();
	DRUM = bellmanford();
	while(1)
	{
		muchii();
		if(!dijkstra())
			break;
		FLUX = INF;
		for(int nod = D ; nod != S ; nod = tata[nod])
			FLUX = min(FLUX, C[tata[nod]][nod] - F[tata[nod]][nod]);
		REZ += (DRUM += d[D]) * FLUX;
		for(int nod = D ; nod != S ; nod = tata[nod])
		{
			F[tata[nod]][nod] += FLUX;
			F[nod][tata[nod]] -= FLUX;
		}
	}
	
	printf("%d\n", REZ);
	
	return 0;
}