Cod sursa(job #832713)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 11 decembrie 2012 09:55:49
Problema Cuplaj maxim de cost minim Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.83 kb

#include <cstdio>
#include <cstring>

const int MAX_SIZE(602);
const int MAX_COST(1 << 30);

int vertices, source, sink, l, r, e, maxflow, min_cost;

int capacity [MAX_SIZE] [MAX_SIZE];
int cost [MAX_SIZE] [MAX_SIZE];
int min_path [MAX_SIZE];
int queue [MAX_SIZE * MAX_SIZE], *pop, *push;
int pred [MAX_SIZE];
bool in_queue [MAX_SIZE];
int edges [MAX_SIZE] [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("cmcm.in","r",stdin);
	std::scanf("%d %d %d",&l,&r,&e);
	vertices = l + r;
	source = 0;
	sink = vertices + 1;
	int x, y, c;
	for (int counter(1) ; counter <= e ; ++counter)
	{
		std::scanf("%d %d %d",&x,&y,&c);
		y += l;
		add(x,y);
		add(y,x);
		edges[x][y] = counter;
		cost[x][y] = c;
		cost[y][x] = -c;
		capacity[x][y] = 1;
		add(source,x);
		add(x,source);
		add(y,sink);
		add(sink,y);
		capacity[source][x] = 1;
		capacity[y][sink] = 1;
	}
	std::fclose(stdin);
}

inline void initialize (void)
{
	std::memset(pred,0,sizeof(*pred) * (vertices + 2));
	std::memset(in_queue,0,sizeof(*in_queue) * (vertices + 2));
	for (int index(source) ; index <= sink ; ++index)
		min_path[index] = MAX_COST;
	in_queue[source] = true;
	min_path[source] = 0;
	*queue = source;
	pop = queue;
	push = queue + 1;
}

inline void BellmanFord (void)
{
	initialize();
	int vertex, neighbor;
	struct edge *iterator;
	while (pop < push)
	{
		vertex = *pop;
		++pop;
		for (iterator = graph[vertex] ; iterator ; iterator = iterator->next)
			if (capacity[vertex][iterator->node] && min_path[vertex] + cost[vertex][iterator->node] < min_path[iterator->node])
			{
				neighbor = iterator->node;
				min_path[neighbor] = min_path[vertex] + cost[vertex][neighbor];
				pred[neighbor] = vertex;
				if (!in_queue[neighbor])
				{
					*push = neighbor;
					++push;
					in_queue[neighbor] = true;
				}
			}
		in_queue[vertex] = false;
	}
}

inline void FordFulkerson (void)
{
	int vertex;
	while (true)
	{
		BellmanFord();
		if (!pred[sink])
			break;
		for (vertex = sink ; vertex != source ; vertex = pred[vertex])
		{
			capacity[pred[vertex]][vertex] = 0;
			capacity[vertex][pred[vertex]] = 1;
		}
		min_cost += min_path[sink];
		++maxflow;
	}
}

inline void print (void)
{
	std::freopen("cmcm.out","w",stdout);
	int i, j;
	std::printf("%d %d\n",maxflow,min_cost);
	for (i = 1 ; i <= l ; ++i)
		for (j = l + 1 ; i <= r ; ++j)
			if (edges[i][j])
				if (!capacity[i][j])
				{
					std::printf("%d ",edges[i][j]);
					break;
				}
	std::putchar('\n');
	std::fclose(stdout);
}

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