Cod sursa(job #501289)

Utilizator clauditzapop claudia clauditza Data 14 noiembrie 2010 17:49:24
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.51 kb
#include <cstdio>
#include <algorithm>

using namespace std;
int n, m, e;
#define nods 301
int v[nods][nods];
int g[nods][nods];
int r[nods], l[nods]; // for matching
int vr[nods], vc[nods]; //deltas
int cr[nods], cc[nods]; //covered?
int p[nods]; //partial
void find_zero() {
	int i, j, mn;
	for (mn = 1<<30, i = 1; i <= n; ++i) if (!cr[i])
		for (j = 1; j <= n; ++j) if (!cc[j])
			mn = min(g[i][j] + vr[i] + vc[j], mn);

	for (i = 1; i <= n; ++i) {
		if (cr[i]) vr[i] += mn;
		if (!cc[i]) vc[i] -= mn;
	}
	for (i = 1; i <= n; ++i) if (!cr[i])
		for (j = 1; j <= n; ++j) if (!cc[j] && g[i][j] + vr[i] + vc[j] ==
				0) {
			if (r[i]) {
				p[i] = j; cr[i] = 1; cc[r[i]] = 0;
				break;
			} else {
				int aux;
				do {aux = l[j]; r[i] = j; l[j] = i; i = aux; j = p[i];}
				while (aux);
				return;
			}
		}
	find_zero();
}
int main() {
	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);
		v[a][b] = i;
		c -= 20001;
		g[a][b] = c;
	}
	n = max(n, m);
	for (int cnt = 0; cnt < n; ++cnt) {
		for (int i = 1; i <= n; ++i) {
			cr[i] = p[i] = 0;
			cc[i] = l[i];
		}
		find_zero();
	}
	int nr = 0, k = 0;
	for (int i = 1; i <= n; ++i) if (r[i] && v[i][r[i]]) {
		++nr;
		k += g[i][r[i]] + 20001;
	}
	printf("%d %d\n", nr, k);
	for (int i = 1; i <= n; ++i) if (r[i] && v[i][r[i]]) {
		printf("%d ", v[i][r[i]]);
	}
	if (nr) printf("\n");
	return 0;
}