Cod sursa(job #639779)

Utilizator ELHoriaHoria Cretescu ELHoria Data 23 noiembrie 2011 22:41:42
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.16 kb
#include <fstream>
#include <vector>
#include <queue>
#define PII pair<int,int>
#define MP make_pair
#define st first
#define nd second

using namespace std;

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

const int INF = int(2e9);
vector<PII> G[605];
int C[605][605] , F[605][605] , edge[605][605];
int N , M , E , TT[605] , D[605] , src , sink , ans;
bool u[605] , improve;

void read_data()
{
	int p , q , cost;
	fin>>N>>M>>E;
	for(int i=1;i<=E;i++)
	{
		fin>>p>>q>>cost;
		p++ ,  q+=N+1;
		G[p].push_back(MP(q,cost));
		G[q].push_back(MP(p,-cost));

		C[p][q] = 1;
		edge[p][q] = i;
	}
}

void build_graph()
{
	src = 1 , sink = N + M + 2;
	for(int i=2;i<=N+1;++i)
	{
		G[src].push_back(MP(i,0));
		G[i].push_back(MP(src,0));
		C[src][i] = 1;
	}
	
	for(int i = N+2;i<=N+M+1;++i)
	{
		G[sink].push_back(MP(i,0));
		G[i].push_back(MP(sink,0));
		C[i][sink] = 1;
	}
}

int bellman()
{
	queue<int> Q;
	int node;
	for(int i=1;i<=N+M+2;++i)
	{
		TT[i] = -1;
		D[i] = INF;
		u[i] = 0;
	}
	D[src] = 0;	u[src] = 1;
	for(Q.push(src);!Q.empty();)
	{
		node = Q.front() , Q.pop();
		u[node] = 0;
		for(vector< PII >::const_iterator w=G[node].begin();w!=G[node].end();++w)
		if(C[node][w->st] > F[node][w->st] && D[w->st] > D[node] + w->nd)
		{
			TT[w->st] = node;
			D[w->st] = D[node] + w->nd;
			if(!u[w->st])
				u[w->st] = 1 , Q.push(w->st);
		}
	}

	if(D[sink]<INF)
	{
		int flux = INF;
		improve = 1;
		for(node = sink;node!=src;node = TT[node])
			flux = min(flux,C[TT[node]][node] - F[TT[node]][node]);

		for(node = sink;node!=src;node = TT[node])
			F[TT[node]][node] +=flux,
			F[node][TT[node]] -=flux;

		return flux * D[sink];
	}

	return 0;
}

void solve()
{
	build_graph();

	do { 
		improve = 0;
		ans+=bellman();
	} while(improve);

	vector<int> edges;
	for(int i = 2;i<=N+1;++i)
		for(int j = N+2;j<sink;++j)
			if(C[i][j] && F[i][j]) {
				edges.push_back(edge[i][j]); 
				break; 
			}

	fout<<edges.size()<<' '<<ans<<'\n';
	for(vector<int>::const_iterator it=edges.begin();it!=edges.end();++it)
		fout<<(*it)<<' ';
}

int main()
{
	read_data();
	solve();
	return 0;
}