Cod sursa(job #578843)

Utilizator mathboyDragos-Alin Rotaru mathboy Data 11 aprilie 2011 17:37:06
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.19 kb
#include <cstdio>
#include <vector>
#include <bitset>
#include <queue>
#define f first
#define s second
#define MAXN 630
#define INF 1000000000
#define VIT vector <pair <int, int> > :: iterator

using namespace std;

vector <pair <int, int> > G[MAXN];
bitset <MAXN> viz;
int D[MAXN], N, M, E, source, dest;
short int matCap[MAXN][MAXN], matFlux[MAXN][MAXN];
int solEdge[MAXN][MAXN], dad[MAXN];
inline bool BF ()
{	
	queue <int> Q;
	viz.reset ();
	
	int nod;
	
	for (int i = source; i <= dest; i++) {
		D[i] = INF;
		dad[i] = 0;
	}
	
	Q.push (source);
	D[source] = 0;
	while (!Q.empty ()) {
		nod = Q.front ();
		Q.pop ();
		viz[nod] = 0;
		
		for (VIT it = G[nod].begin (); it != G[nod].end (); it++) 
			if (matCap[nod][it -> f] > matFlux[nod][it -> f] && D[it -> f] > D[nod] + it -> s) {
				D[it -> f] = D[nod] + it -> s;
				dad[it -> f] = nod;
				if (viz[it -> f] == 0) {
					viz[it -> f] = 1;
					Q.push (it -> f);
				}
			}
	}
	return D[dest] != INF;
}	
int main ()
{

	freopen ("cmcm.in", "r", stdin);
	freopen ("cmcm.out", "w", stdout);


	scanf ("%d %d %d\n", &N, &M, &E);
	
	source = 1;
	dest = N + M + 2;
	
	int x, y, c, i, j;
// Building Graph
	for (i = 2; i <= N + 1; i++) {
		G[source].push_back (make_pair (i, 0));
		G[i].push_back (make_pair (source, 0));
		matCap[source][i] = 1;
	}

	for (i = N + 2; i <= N + M + 1; i++) {
		G[i].push_back (make_pair (dest, 0));
		G[dest].push_back (make_pair (i, 0));
		matCap[i][dest] = 1;
	}

	for (i = 1; i <= E; i++) {
		
		scanf ("%d %d %d\n", &x, &y, &c);
		
		x += 1;	
		y += N + 1;

		G[x].push_back (make_pair (y, c));
		G[y].push_back (make_pair (x, -c));
		
		matCap[x][y] = 1;
		solEdge[x][y] = i;

	}
	
	int fmin, flow = 0, flowcost = 0, nod;
	while (BF ()) {
		
		nod = dest;
		fmin = INF;
		
		for (i = nod; i != source; i = dad[i])
			fmin = min (matCap[dad[i]][i] - matFlux[dad[i]][i], fmin);
		
		for (i = nod; i != source; i = dad[i]) {
			matFlux[dad[i]][i] += fmin;
			matFlux[i][dad[i]] -= fmin;
		}
		flow += fmin;
		flowcost += fmin * D[dest];

	}
	
	printf ("%d %d\n", flow, flowcost);

	for (i = 2; i <= N + 1; i++)
		for (j = N + 2; j <= N + M + 1; j++)
			if (matCap[i][j] && matFlux[i][j]) {
				printf ("%d ", solEdge[i][j]);
				break;
			}

	return 0;
}