Cod sursa(job #609503)

Utilizator stay_awake77Cangea Catalina stay_awake77 Data 21 august 2011 19:11:59
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.31 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
#include <algorithm>

#define INF 0x3f3f3f3f
#define NMAX 605
#define pb push_back
#define mp make_pair
#define nod first
#define cost second
#define MIN(a,b) (a<b) ? a : b

using namespace std;

ifstream in("cmcm.in");
ofstream out("cmcm.out");

int N1, N2, E, S, D, i, j, x, y, cost, Nod, FluxCt, FluxMax, CostMin;
int C[NMAX][NMAX], F[NMAX][NMAX], T[NMAX], Dist[NMAX], M[NMAX][NMAX];
bool USED[NMAX];
vector< pair< int, int > > G[NMAX];
vector< pair< int, int > >::iterator Vecin;

inline bool BellmanFord()
{
	memset( T, 0, sizeof(T) );
	memset( USED, false, sizeof(USED) );
	memset( Dist, INF, sizeof(Dist) );
	
	queue< int > Q;
	Q.push( S );
	USED[S] = true;
	Dist[S] = 0;
	
	while( !Q.empty() )
	{
		Nod = Q.front();
		Q.pop();
		USED[Nod] = false;
		
		if( Nod == D ) continue;
		
		for( Vecin = G[Nod].begin(); Vecin != G[Nod].end(); Vecin++ )
			if( F[Nod][(*Vecin).nod] < C[Nod][(*Vecin).nod] && Dist[ (*Vecin).nod ] > Dist[Nod] + (*Vecin).cost )
			{
				Dist[ (*Vecin).nod ] = Dist[Nod] + (*Vecin).cost;
				T[ (*Vecin).nod ] = Nod;
				
				if( !USED[ (*Vecin).nod ] )
				{
					USED[ (*Vecin).nod ] = true;
					Q.push( (*Vecin).nod );
				}
			}
	}
	
	return ( Dist[D] != INF );
}

int main()
{
	in >> N1 >> N2 >> E;
	S = 0; D = N1 + N2 + 1;
	memset( M, 0, sizeof(M) );
	
	for( i = 1; i <= E; i++ )
	{
		in >> x >> y >> cost;
		M[x][N1+y] = M[N1+y][x] = i;
		
		C[x][N1+y] = 1;
		
		G[x].pb( mp( N1+y, cost ) );
		G[N1+y].pb( mp( x, -cost ) );
	}
	
	for( i = 1; i <= N1; i++ )
	{
		C[S][i] = 1;
		
		G[S].pb( mp( i, 0 ) );
		G[i].pb( mp( S, 0 ) );
	}
	for( i = N1 + 1; i <= N1 + N2; i++ )
	{
		C[i][D] = 1;
		
		G[i].pb( mp( D, 0 ) );
		G[D].pb( mp( i, 0 ) );
	}
	
	for( FluxMax = CostMin = 0; BellmanFord(); FluxMax += FluxCt, CostMin += FluxCt * Dist[D] )
	{
		FluxCt = INF;
		
		for( Nod = D; Nod != S; Nod = T[Nod] )
			FluxCt = MIN( FluxCt, C[ T[Nod] ][Nod] - F[ T[Nod] ][Nod] );
		
		for( Nod = D; Nod != S; Nod = T[Nod] )
			F[ T[Nod] ][Nod] += FluxCt, F[Nod][ T[Nod] ] -= FluxCt;
	}
	
	out << FluxMax << ' ' << CostMin << '\n';
	for( i = 1; i <= N1; i++ )
		for( j = N1 + 1; j <= N1 + N2; j++ )
			if( C[i][j] && F[i][j] ) out << M[i][j] << ' ';
	
	return 0;
}