Cod sursa(job #815637)

Utilizator ahmed.abdraboahmed.abdrabo ahmed.abdrabo Data 17 noiembrie 2012 11:30:01
Problema Cuplaj maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.48 kb
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <queue>
#include <set>
#include <vector>

using namespace std;

inline int next_int() {
	int n = 0, sign = 1;
	char c = getchar_unlocked();
	while (!('0' <= c && c <= '9')) {
		sign *= c == '-' ? -1 : 1;
		c = getchar_unlocked();
	}
	while ('0' <= c && c <= '9') {
		n = n * 10 + c - '0';
		c = getchar_unlocked();
	}
	return sign * n;
}

const int MAX_V = 602;
const int INF = 1e9;

int V, E, min_cost, max_flow, path_cost, path_flow, where;
int from[1000000], to[1000000], capacity[1000000], cost[1000000];
int e_begin[1000], e_next[1000000];
int dist[1000], prev[1000];
int Q[1000];
bool seen[1000];

inline void add_edge(int a, int b, int c, int d) {
	from[E] = a, to[E] = b, capacity[E] = c, cost[E] = +d;
	E++;
	from[E] = b, to[E] = a, capacity[E] = 0, cost[E] = -d;
	E++;
}

inline void run(const int source, const int sink) {
	memset(e_begin, -1, sizeof e_begin);
	for (int e = 0; e < E; e++) {
		e_next[e] = e_begin[from[e]];
		e_begin[from[e]] = e;
	}
	while (true) {
		for (int v = 0; v < V; v++) {
			prev[v] = -1;
			seen[v] = false;
			dist[v] = INF;
		}
		dist[source] = 0;
		int front = 0, back = 0;
		Q[back++] = source;
		seen[source] = true;
		while (back - front > 0) {
			int u = Q[front++];
			for (int e = e_begin[u]; e != -1; e = e_next[e]) {
				if (dist[from[e]] < INF && capacity[e] && dist[from[e]] + cost[e] < dist[to[e]]) {
					dist[to[e]] = dist[from[e]] + cost[e];
					prev[to[e]] = e;
					if (!seen[to[e]]) {
						seen[to[e]] = true;
						Q[back++] = to[e];
					}
				}
			}
			seen[u] = false;
		}
		if (dist[sink] == INF) {
			break;
		}
		for (where = sink; where != source; where = from[prev[where]]) {
			capacity[prev[where] ^ 0]--;
			capacity[prev[where] ^ 1]++;
		}
		min_cost += dist[sink];
		max_flow++;
	}
}

int main() {
	freopen("cmcm.in", "r", stdin);
	freopen("cmcm.out", "w", stdout);
	int c1 = next_int();
	int c2 = next_int();
	int n = c1 + c2 + 2;
	int source = c1 + c2;
	int sink = c1 + c2 + 1;
	V = n;
	for (int i = 0; i < c1; i++) {
		add_edge(source, i, 1, 0);
	}
	for (int i = 0; i < c2; i++) {
		add_edge(c1 + i, sink, 1, 0);
	}
	int m = next_int();
	int e = E;
	for (int i = 0; i < m; i++) {
		int x = next_int();
		int y = next_int();
		int z = next_int();
		add_edge(x - 1, c1 + y - 1, 1, z);
	}
	run(source, sink);
	printf("%d\n", max_flow);
	printf("%d\n", min_cost);
	for (int i = 0; i < m; i++) {
		if (capacity[e + i * 2] == 0) {
			printf("%d ", i + 1);
		}
	}
	return 0;
}