Cod sursa(job #806865)

Utilizator danalex97Dan H Alexandru danalex97 Data 3 noiembrie 2012 17:37:22
Problema Cuplaj maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.39 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 Rflu[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,Sol;

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]] - Rflu[i][Leg[i][j]] <= 0 || Dist[i] + Cost[i][Leg[i][j]] >= Dist[Leg[i][j]] )
                continue;

            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] - Rflu[Dad[i]][i] );

		for (int i = End; i != Start; i = Dad[i])
		{
			Rflu[Dad[i]][i] += Vmin;
			Rflu[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();
	}

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