Cod sursa(job #476390)

Utilizator vlad.maneaVlad Manea vlad.manea Data 10 august 2010 20:42:03
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.94 kb
//

#ifndef _ALGORITHM_H
#define _ALGORITHM_H
#include <fstream>
using namespace std;

/**
	Algorithm abstract class
	specifies protocol
*/
class Algorithm
{
protected:

	istream &in;
	ostream &out;

	/**
		algorithm method
		instantiates i/o
	*/
	Algorithm(istream &, ostream &);
};

#endif

#ifndef _MAXFLOWMINCOST_H
#define _MAXFLOWMINCOST_H

#include <queue>
#include <vector>
using namespace std;

/**
	MaxFlowMinCost class
	solves the maximum flow with minimum cost in a network problem
*/
class MaxFlowMinCost: public Algorithm
{
	int N, M, S, D, A;
	vector< vector<int> > Cap, Cst, Flw, Deg;
	vector<int> Dst, Ftr, Mxf;
	queue<int> Que;

public:

	/**
		maxflowmincost method
		runs algorithm
	*/
	MaxFlowMinCost(istream &, ostream &);

private:

	/**
		read method
		reads input
	*/
	void Read();

	/**
		solve method
		solves problem
	*/
	void Solve();

	/**
		write method
		writes output
	*/
	void Write();

	/**
		flow method
		computes flow
	*/
	bool Flow();
};

#endif


/**
	algorithm method
	instantiates i/o
*/
Algorithm::Algorithm(istream &inp, ostream &outp): in(inp), out(outp)
{

}


/**
	maxflowmincost method
	runs algorithm
*/
MaxFlowMinCost::MaxFlowMinCost(istream &in, ostream &out): Algorithm(in, out), A(0)
{
	Read();
	Solve();
	Write();
}

/**
	read method
	reads input
*/
void MaxFlowMinCost::Read()
{
	int x, y, c, z;
	vector<int> Aux1, Aux2;

	in >> N >> M >> S >> D;
	Aux2.assign(N + 1, 0), Ftr.assign(N + 1, 0), Mxf.assign(N + 1, 0);
	Dst.assign(N + 1, numeric_limits<int>::max());

	for (c = 0; c <= N; ++c)
	{
		Deg.push_back(Aux1), Cap.push_back(Aux2), Cst.push_back(Aux2), Flw.push_back(Aux2);
	}

	while (M--)
	{
		in >> x >> y >> c >> z;
		Deg[x].push_back(y), Deg[y].push_back(x);
		Cap[x][y] = c, Cst[x][y] = z, Cst[y][x] = -z;
	}
}

/**
	solve method
	solves problem
*/
void MaxFlowMinCost::Solve()
{
	M = numeric_limits<int>::max();

	while (Flow());
}

/**
	write method
	writes output
*/
void MaxFlowMinCost::Write()
{
	out << A;
}

/**
	flow method
	computes flow
*/
bool MaxFlowMinCost::Flow()
{
	int i, u, v;
	vector<int>::iterator j;

	for (i = 1; i <= N; ++i)
	{
		Dst[i] = M;
		Mxf[i] = 0;
	}

	Dst[S] = 0;
	Mxf[S] = M;
	Que.push(S);

	while (!Que.empty())
	{
		u = Que.front();
		Que.pop();

		for (j = Deg[u].begin(); j != Deg[u].end(); ++j)
		{
			v = *j;

			if (Cap[u][v] > Flw[u][v] && Dst[v] > Dst[u] + Cst[u][v])
			{
				Dst[v] = Dst[u] + Cst[u][v], Ftr[v] = u;
				Mxf[v] = min(Mxf[u], Cap[u][v] - Flw[u][v]);

				if (v != D)
				{
					Que.push(v);
				}
			}
		}
	}

	if (Dst[D] == M)
	{
		return false;
	}

	i = Mxf[D];
	A += Dst[D] * i;

	for (v = D, u = Ftr[D]; v != S; v = u, u = Ftr[u])
	{
		Flw[u][v] += i;
		Flw[v][u] -= i;
	}

	return true;
}


//



//#include "maxflowmincost.h"



int main()
{
	ifstream fin("fmcm.in");
	ofstream fout("fmcm.out");
	MaxFlowMinCost mflow(fin, fout);

	fin.close();
	fout.close();
	return 0;
}