Cod sursa(job #714948)

Utilizator eukristianCristian L. eukristian Data 16 martie 2012 12:57:58
Problema Cuplaj maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.61 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 602
#define source 0
#define sink 601
#define INF 0x7fffffff

typedef struct tagNode{
	struct tagNode *next;
	int key, cost;
} node;

int n, m, e;
node *graph[MAXN];
int edge[MAXN][MAXN], dist[MAXN];

short flow[MAXN][MAXN], capacity[MAXN][MAXN], queue[MAXN * MAXN], prev[MAXN];
bool in_queue[MAXN];

inline void add(int a, int b, int cost)
{
	node *q = (node *) malloc(sizeof(node));
	q->key = b;
	q->cost = cost;
	q->next = graph[a];
	graph[a] = q;
}
void read();
void solve();
int bfs()
{
	int left = 0, right = 0;
	queue[0] = source;
	
	for (int i = 1 ; i <= n + m ; ++i)
	{
		dist[i] = INF;
		in_queue[i] = false;
	}
	
	dist[sink] = INF;
	in_queue[sink] = false;
	dist[source] = 0;
	in_queue[source] = true;
	
	while (left <= right)
	{
		int nd = queue[left++];
		
		node *q = graph[nd];
		while (q)
		{
			if ((dist[q->key] > dist[nd] + q->cost) && (capacity[nd][q->key] - flow[nd][q->key] > 0))
			{
				dist[q->key] = dist[nd] + q->cost;
				prev[q->key] = nd;
				
				if (!in_queue[q->key])
				{
					queue[++right] = q->key;
					in_queue[q->key] = true;
				}
			}
			q = q->next;
		}
		in_queue[nd] = false;
	}
	
	if (dist[sink] != INF)
	{
		int minIncrease = INF;
		for (int crt = sink ; crt != source ; crt = prev[crt])
			if (minIncrease > capacity[prev[crt]][crt] - flow[prev[crt]][crt])
				minIncrease = capacity[prev[crt]][crt] - flow[prev[crt]][crt];
		
		for (int crt = sink ; crt != source ; crt = prev[crt])
		{
			flow[prev[crt]][crt] += minIncrease;
			flow[crt][prev[crt]] -= minIncrease;
		}
		
		return dist[sink] * minIncrease;
	}
	
	return 0;
}

int main()
{
	read();
	solve();
	
	return 0;
}

void read()
{
	freopen("cmcm.in", "r", stdin);
	freopen("cmcm.out","w", stdout);
	
	scanf("%d%d%d", &n, &m, &e);
	
	for (int i = 1 ; i <= e ; ++i)
	{
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		add(a, b + n, c);
		add(b + n, a, -c);
		capacity[a][b + n] = 1;
		
		edge[a][b + n] = i;
	}
	
	for (int i = 1 ; i <= n ; ++i)
	{
		add(source, i, 0);
		add(i, source, 0);
		capacity[source][i] = 1;
	}
	
	for (int i = n + 1 ; i <= n + m ; ++i)
	{
		add(i, sink, 0);
		add(sink, i, 0);
		capacity[i][sink] = 1;
	}
}

void solve()
{
	int totalCost = 0, crtCost, nr = 0;
	while (crtCost = bfs())
		totalCost += crtCost;
		
	for (int i = 1 ; i <= n ; ++i)
		for (int j = n + 1 ; j <= n + m ; ++j)
			if (capacity[i][j] && flow[i][j])
			{	
				nr++;break;
			}
			
	printf("%d %d\n", nr, totalCost);
	
	for (int i = 1 ; i <= n ; ++i)
		for (int j = n + 1 ; j <= n + m ; ++j)
			if (capacity[i][j] && flow[i][j])
			{	
				printf("%d ", edge[i][j]);break;
			}
	printf("\n");
}