Cod sursa(job #758546)

Utilizator alexeiIacob Radu alexei Data 15 iunie 2012 22:43:44
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.7 kb
#include<cstdio>
#include<iostream>
#include<vector>
#include<queue>
using namespace std;

#define inf 0x3f3f3f3f
#define NMAX 604

int N,M,E;
int Source, Dest, Ans;

int Cap[NMAX][NMAX] , D[NMAX] , T[NMAX], ind[NMAX][NMAX];
vector < pair< int, int > > G[NMAX];

vector< bool > viz( NMAX, false );

class comp{
public:
	bool operator() (const int& lhs, const int &rhs) {
		return D[lhs] > D[rhs];
	}
};

int BF()
{
	int nod, vec, val, edge;
	unsigned int i,sz;

	for( int i = 1; i <= Dest; ++i )
		viz[i] = false, D[i] = inf, T[i] = 0;

	//priority_queue< int , vector<int> , comp > Q;
	queue < int > Q;

	D[ Source ] = 0; viz[ Source ] = true;
	Q.push( Source );

	while( !Q.empty() )
	{
		nod = Q.front();
		val = D[nod];
		Q.pop();

		//if( nod == Dest )
		//	break;
		
		viz[nod] = false;

		for( i = 0, sz = G[nod].size(); i < sz; ++i )
		{
			vec = G[nod][i].first , edge = G[nod][i].second;

			if( !Cap[nod][vec] )
				continue;

			if( val + edge < D[vec] )
			{
				T[vec] = nod;
				D[vec] = val+edge;

				if( viz[vec] == false )
					Q.push(vec) , viz[vec] = true;	 
			}
		}
	}

	if( D[ Dest ] == inf )
		return 0;

	int flow = 0;
	// Dinic no good here

	int t_flow = inf;
	for( nod = Dest; nod != Source; nod = T[nod] )
		t_flow = min( t_flow, Cap[ T[nod] ][ nod ] );

	for( nod = Dest; nod != Source; nod = T[nod] )
	{
		Cap[ T[nod] ][ nod ] -= t_flow;
		Cap[ nod ][ T[nod] ] += t_flow;
	}
	
	Ans += D[ Dest ] * t_flow;
	flow += t_flow;
	
	return flow;
}


void run_max_flow()
{
	int max_matching = 0 , flow = 1;

	while( flow )
	{
		flow = BF();
		max_matching += flow;
	}

	cout << max_matching << " " << Ans << "\n";
}


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

	cin >> N >> M >> E;

	int A, B, C;

	for( int k = 1; k <= E; ++k )
	{
		cin >> A >> B >> C;

		B += N;

		G[A].push_back( make_pair( B , C ) );
		G[B].push_back( make_pair( A, -C ) );

		Cap[ A ][ B ] = 1;
		ind[ A ][ B ] = ind[ B ][ A ] = k;
	}

	Source = N + M + 2;
	Dest = Source + 1;

	for( int i = 1; i <= N; ++i )
	{
		Cap[ Source ][ i ]= 1;
		G[ Source ].push_back( make_pair( i, 0 ) );
		G[ N+i ].push_back( make_pair( Source, 0 ) );
	}

	for( int i = 1; i <= M; ++i )
	{
		Cap[ N+i ][ Dest ] = 1;
		G[ N+i ].push_back( make_pair( Dest , 0 ) );
		G[ Dest ].push_back( make_pair( N+i , 0 ) );
	}

	run_max_flow();

	bool first = true;

	for( int i = 1; i <= N; ++i )
		for( int j = 0 , sz = G[i].size(); j < sz; ++j )
		{
			int vec = G[i][j].first;
			if( !Cap[i][vec] )
				if( !first ) cout << " " << ind[i][vec];
				else		 cout << ind[i][vec] , first = false;
		}	

	return 0;
}