Cod sursa(job #1222994)

Utilizator Luncasu_VictorVictor Luncasu Luncasu_Victor Data 24 august 2014 23:30:41
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2 kb
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
#define MAX 1010
#define INF 0xFFFFFFF

vector<int> Graph[MAX];
queue<int> Q[2];
int N, M, E, Capacity[MAX][MAX], Cost[MAX][MAX], From[MAX], C[MAX], Flow[MAX][MAX], MaxFlow, MinCost, S, D, Ord[MAX][MAX];

bool Bellman() {
	int X, Y, Z, A = 1, B = 0;
	Q[0].push(1);
	for (int i = 1; i <= D; i++) {
		C[i] = INF;
	}
	C[1] = 0;
	for (int i = 1; i <= D; i++) {
		A ^= 1;
		B ^= 1;
		while (Q[A].size()) {
			X = Q[A].front();
			Q[A].pop();
			for (int i = 0; i < Graph[X].size(); i++){
				Y = Graph[X][i];
				if (Capacity[X][Y] > Flow[X][Y] && C[Y] > C[X] + Cost[X][Y]) {
					From[Y] = X;
					C[Y] = C[X] + Cost[X][Y];
					Q[B].push(Y);
				}
			}
		}	
	}
	return C[D] != INF;
}

int main() {
	int X, Y, Z;

	freopen("cmcm.in","r",stdin);
	freopen("cmcm.out","w",stdout);
	
	scanf("%d %d %d", &N, &M, &E);
	for (int i = 1; i <= E; i++) {
		scanf("%d %d %d", &X, &Y, &Z);
		X += 1;
		Y += N + 1;
		Graph[X].push_back(Y);
		Graph[Y].push_back(X);
		Capacity[X][Y] = 1;
		Cost[X][Y] = Z;
		Cost[Y][X] = -Z;
		Ord[X][Y] = i;
	}
	S = 1;
	D = N + M + 2;
	for (int i = 2; i <= N+1; i++) {
		Graph[S].push_back(i);
		Graph[i].push_back(S);
		Capacity[S][i] = 1;
	}
	for (int i = N+2; i <= N+M+1; i++) {
		Graph[i].push_back(D);
		Graph[D].push_back(i);
		Capacity[i][D] = 1;
	}
	
	while (Bellman()) {
		Z = INF;
		for (X = D; X != 1; X = From[X]) {
			Z = min(Z, Capacity[From[X]][X] - Flow[From[X]][X]); 
		}
		if (Z != INF && Z > 0) {
			MaxFlow += Z;
			for (X = D; X != 1; X = From[X]) {
				Flow[From[X]][X] += Z;
				Flow[X][From[X]] -= Z;
				MinCost += Z * Cost[From[X]][X]; 
			}
		}	 
	}
	
	printf("%d %d\n", MaxFlow, MinCost);
	for (int i = 2; i < D; i++)
	for (int j = 2; j < D; j++) {
		if (Flow[i][j]>0) {
			printf("%d ", Ord[i][j]);
		}
	}

	return 0;
}