Cod sursa(job #829729)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 5 decembrie 2012 19:38:54
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.5 kb

#include <cstdio>
#include <cstring>

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

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

int capacity [MAX_SIZE] [MAX_SIZE];
int cost [MAX_SIZE] [MAX_SIZE];
int queue [1000010], *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];

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);
		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)
{
	//std::memset(mark,0,n);
	//std::memset(pred,0,sizeof(*pred) * n);
	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;
	struct edge *iterator;
	while (pop < push)
	{
		vertex = *pop;
		++pop;
		for (iterator = graph[vertex] ; iterator ; iterator = iterator->next)
		{
			if (capacity[vertex][iterator->node])
				if (path_cost[vertex] + cost[vertex][iterator->node] < path_cost[iterator->node])
				{
					path_cost[iterator->node] = path_cost[vertex] + cost[vertex][iterator->node];
					pred[iterator->node] = vertex;
					if (!mark[iterator->node])
					{
						*push = iterator->node;
						++push;
						mark[iterator->node] = 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_capacity * cost[pred[vertex]][vertex];
		}
	}
}

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