Cod sursa(job #806847)

Utilizator danalex97Dan H Alexandru danalex97 Data 3 noiembrie 2012 17:11:07
Problema Cuplaj maxim de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.26 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>

using namespace std;

const int Nmax = 310;
const int Mmax = 50011;
const int oo = 1<<30;

int Flux[Nmax][Nmax];
int Cost[Nmax][Nmax];

vector< int > Leg[Nmax];
vector< pair<int,int> > Edges;
queue< int > Q;

int N,M,T,Start,End;
int Rez,Drum;

int Dist[Nmax],Dad[Nmax],Used[Nmax];

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

int Bellman()
{
	for (int i=1;i<=N+M+2;++i)
	{
		Dad[i]=-1;
		Dist[i]=oo;
	}

	Dist[Start] = 0;
	Q.push( Start );
	memset(Used, 0, sizeof(Used));
	Used[Start] = 1;

	while ( Q.size() )
	{
		int i = Q.front();

		for (int j=0;j<int( Leg[i].size() );++j)
			if ( Flux[i][Leg[i][j]] > 0 && Dist[i] + Cost[i][Leg[i][j]] < Dist[Leg[i][j]] )
				{
					Dist[ Leg[i][j] ] = Dist[i] + Cost[i][ Leg[i][j] ];
					Dad[ Leg[i][j] ] = i;

					if ( !Used[ Leg[i][j] ] )
					{
						Q.push( Leg[i][j] );
						Used[ Q.back() ] = 1;
					}
				}

		Q.pop();
		Used[i]=0;
	}

	if ( Dist[End] != oo )
	{
		int Vmin = oo;
		Drum = 1;

		for (int i = End; i != Start; i = Dad[i])
			Vmin = min(Vmin, Flux[Dad[i]][i] );

		for (int i = End; i != Start; i = Dad[i])
		{
			Flux[Dad[i]][i] -= Vmin;
			Flux[i][Dad[i]] += Vmin;
		}

		return Vmin * Dist[End];
	}

	return 0;
}

int main()
{
    Start = 1, End = 2 ;
	F>>N>>M>>T;
	for (int i=1;i<=T;++i)
	{
		int x,y,cos;
		F>>x>>y>>cos;

        x+=2;
        y+=N+2;

		Flux[x][y]=1;
		Cost[x][y]=cos;
		Cost[y][x]=-cos;

		Leg[x].push_back( y );
		Leg[y].push_back( x );
		Edges.push_back( make_pair(x,y) );
	}

	for (int i=3;i<=N+2;++i)
	{
	    int x=1, y=i;
        Flux[x][y]=1;
        Leg[x].push_back( y );
		Leg[y].push_back( x );
	}

	for (int i=N+3;i<=M+N+2;++i)
	{
	    int x=i, y=2;
        Flux[x][y]=1;
        Leg[x].push_back( y );
		Leg[y].push_back( x );
	}

	Rez=0;
	Drum=1;

	while ( Drum )
	{
		Drum=0;
		Rez+=Bellman();
	}

    int Sol = 0;
    for (int i=0; i<Edges.size(); ++i)
        if ( Flux[Edges[i].first][Edges[i].second] > 0 )
            ++Sol;
    G<<Sol<<' '<<Rez<<'\n';
    for (int i=0; i<Edges.size(); ++i)
        if ( Flux[Edges[i].first][Edges[i].second] > 0 )
            G<<i+1<<' ';
    G<<'\n';
}