Cod sursa(job #829784)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 5 decembrie 2012 20:45:22
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.56 kb

#include <cstdio>
#include <cstring>
#include <vector>

const int MAX_SIZE(351);
const int MAX_COST(1 << 30);
const int MAX_CAPACITY(10000);
const int QUEUE_SIZE(1000000);

int n, m, source, sink;
long long min_cost;

int capacity [MAX_SIZE] [MAX_SIZE];
int cost [MAX_SIZE] [MAX_SIZE];
int queue [QUEUE_SIZE], *pop, *push;
int pred [MAX_SIZE];
int path_cost [MAX_SIZE];
bool mark [MAX_SIZE];
/*
struct edge
{
	int node;
	struct edge *next;
} *graph [MAX_SIZE];
*/
std::vector<int> graph [MAX_SIZE];
/*
inline void add (int x, int y)
{
	struct edge *new_edge(new struct edge);
	new_edge->node = y;
	new_edge->next = graph[x];
	graph[x] = new_edge;
}
*/
inline void read (void)
{
	std::freopen("fmcm.in","r",stdin);
	std::scanf("%d%d%d%d",&n,&m,&source,&sink);
	int x, y, c, z;
	for (int counter(0) ; counter < m ; ++counter)
	{
		std::scanf("%d%d%d%d",&x,&y,&c,&z);
		//add(x,y);
		//add(y,x);
		graph[x].push_back(y);
		graph[y].push_back(x);
		capacity[x][y] = c;
		cost[x][y] = z;
		cost[y][x] = -z;
	}
	std::fclose(stdin);
}

inline void print (void)
{
	std::freopen("fmcm.out","w",stdout);
	std::printf("%lld\n",min_cost);
	std::fclose(stdout);
}

inline void initialize (void)
{
	for (int index(1) ; index <= n ; ++index)
		path_cost[index] = MAX_COST;
	path_cost[source] = 0;
	pred[source] = 0;
	pred[sink] = 0;
	pop = queue;
	push = queue + 1;
	*queue = source;
}

inline void BellmanFord (void)
{
	initialize();
	int vertex, neighbor, size, i;
	struct edge *iterator;
	while (pop < push)
	{
		vertex = *pop;
		++pop;
		for (i = 0, size = graph[vertex].size() ; i < size ; ++i)
			if (capacity[vertex][graph[vertex][i]])
			{
				neighbor = graph[vertex][i];
				if (path_cost[vertex] + cost[vertex][neighbor] < path_cost[neighbor])
				{
					path_cost[neighbor] = path_cost[vertex] + cost[vertex][neighbor];
					pred[neighbor] = vertex;
					if (!mark[neighbor])
					{
						*push = neighbor;
						++push;
						mark[neighbor] = true;
					}
				}
			}
		mark[vertex] = false;
	}
}

inline void FordFulkerson (void)
{
	int vertex, path_capacity;
	while (true)
	{
		BellmanFord();
		if (!pred[sink])
			break;
		path_capacity = MAX_CAPACITY;
		for (vertex = sink ; vertex != source ; vertex = pred[vertex])
			if (capacity[pred[vertex]][vertex] < path_capacity)
				path_capacity = capacity[pred[vertex]][vertex];
		for (vertex = sink ; vertex != source ; vertex = pred[vertex])
		{
			capacity[pred[vertex]][vertex] -= path_capacity;
			capacity[vertex][pred[vertex]] += path_capacity;
		}
		min_cost += path_cost[sink] * path_capacity;
	}
}

int main (void)
{
	read();
	FordFulkerson();
	print();
	return 0;
}