Cod sursa(job #1603264)

Utilizator TeodorCotetCotet Teodor TeodorCotet Data 17 februarie 2016 12:39:58
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.47 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <bitset>
#include <queue>

using namespace std;

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

const int NMAX = 600;
const int MMAX = 50000;
const int INF = 0x7fffffff;

int l; int r; int n; int m;

vector< vector<int> > g(NMAX + 2, vector<int>(0));
vector< pair<int, int> > edges;

int cost[NMAX + 2][NMAX + 2];
int res[NMAX + 2][NMAX + 2];

int before[NMAX + 2];

int nrMuc; int costMin;


void read() {

	fin >> l >> r >> m;

	n = l + r;

	for(int i = 1; i <= m ; ++i) {
		
		int x; int y;
		fin >> x >> y;
		y = l + y;

		fin >> cost[x][y];
		cost[y][x] = -cost[x][y];
		res[x][y] = 1;

		g[x].push_back(y);
		g[y].push_back(x);
		edges.push_back({x, y});
	}	
}

void construct() {

	for(pair<int, int> edge : edges) {

		g[0].push_back(edge.first);
		g[edge.first].push_back(0);
		res[0][edge.first] = 1;
	
		g[n + 1].push_back(edge.second);
		g[edge.second].push_back(n + 1);
		res[edge.second][n + 1] = 1;
		//costurile muchilor  adaugate e 0
	}
}

bool bellmanFord(int source, int dest, vector< vector<int> >& g, int& costTotal) {

	vector<int> dist(NMAX + 2, INF);
	bitset<NMAX + 2> inQueue;
	queue<int> q;

	q.push(source);
	dist[source] = 0;
	inQueue[source] = true;
	

	for(; q.empty() == false ; q.pop() ) {

		int node = q.front();
		inQueue[node] = false;

		for(int x : g[node]) {

			int newD = dist[node] + cost[node][x];
			
			if(res[node][x] > 0 && newD < dist[x]) {
				dist[x] = newD;
				before[x] = node;

				if(inQueue[x] == false) 
					inQueue[x] = true , q.push(x);
			}
		}
	}

	costTotal = dist[dest];

	return (dist[dest] != INF);
}

void solve(int source, int dest, vector< vector<int> >& g) {

	construct();

	before[source] = source;

	int costTotal;

	while(bellmanFord(source, dest, g, costTotal)) {

		int x = dest;
		int maxFlow = INF;

		for( ; before[x] != x ; x = before[x])
			maxFlow = min(maxFlow, res[before[x]][x]);
		
		x = dest;
		nrMuc++;

		costMin += maxFlow * costTotal;
		
		for( ; before[x] != x ; x = before[x]) {
			res[before[x]][x] -= maxFlow;
			res[x][before[x]] += maxFlow;
		}
	}
}

void print() {

	fout << nrMuc <<  " " << costMin << '\n'; 

	int cnt = 0; 

	for(pair<int,int> edge : edges) {
		
		cnt++;
		if(res[edge.first][edge.second] == 0)
			fout << cnt << " "; 
	}
}

int main() {

	read();

	solve(0, n + 1, g);

	print();

	return 0;
}