Cod sursa(job #2390909)

Utilizator vlad_popaVlad Popa vlad_popa Data 28 martie 2019 14:33:54
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-32 Status done
Runda Arhiva educationala Marime 2.4 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <unordered_map>
#include <climits>
#include <algorithm>


#define MAXN (605)


using pii = std::pair<int, int>;
std::vector<pii> listN[MAXN];
int cap[MAXN][MAXN];
int flow[MAXN][MAXN];
int edgeIndex[MAXN][MAXN];

bool bellmanFord(int N, int src, int dst)
{
	std::vector<int> que[2] = {std::vector<int>(N+1), std::vector<int>(N+1)};	
	std::vector<int> d(N, INT_MAX/2);
	std::vector<int> parent(N, -1);
	std::vector<int> isInQue(N);
	int fst = 0, lst = 1;
	
	que[fst][0] = 1;
	que[fst][1] = src;
	d[src] = 0;
	
	for (int step = 1; step <= N+1; ++ step, fst ^= 1, lst ^= 1) {
		que[lst][0] = 0;
		for (int k = 1; k <= que[fst][0]; ++ k) {
			int curNode = que[fst][k];
			for (auto nb : listN[curNode]) {
				if (cap[curNode][nb.first] - flow[curNode][nb.first] > 0 && d[nb.first] > d[curNode] + nb.second) {
					d[nb.first] = d[curNode] + nb.second;
					parent[nb.first] = curNode;
					if (isInQue[nb.first] != step) {
						isInQue[nb.first] = step;
						que[lst][++que[lst][0]] = nb.first;
					}
				}
			}
		}
	} 
	
	if (d[dst] < (INT_MAX/2)) {
		int minFlow = INT_MAX/2;
		for (int pathN = dst; pathN != 0; pathN = parent[pathN]) {
			minFlow = std::min(minFlow, cap[parent[pathN]][pathN]-flow[parent[pathN]][pathN]);
		}
		for (int pathN = dst; pathN != 0; pathN = parent[pathN]) {
			flow[parent[pathN]][pathN] += minFlow;
			flow[pathN][parent[pathN]] -= minFlow;
		}
		
		return 1;
	}
	return 0;
}

int main ()
{
	/* code */
	std::ifstream in("cmcm.in");
	
	int N, M, E;
	in >> N >> M >> E;
	int src = 0, dst = N+M+1;
	for (int i = 0; i < E; ++ i) {
		int x, y, c;
		in >> x >> y >> c;
		listN[x].push_back({y + N, c});
		listN[y + N].push_back({x, -c});
		cap[x][y + N] = 1;
		
		edgeIndex[x][y + N] = i+1;
	}
	
	in.close();
	
	for (int i = 1; i <= N; ++ i) {
		listN[0].push_back({i, 0});
		cap[0][i] = 1;
	}
	for (int i = 1; i <= M; ++ i) {
		listN[N + i].push_back({dst, 0});
		cap[N + i][dst] = 1;
	}
	
	while (bellmanFord(N + M + 2, src, dst)); 
	
	int cost = 0;
	std::vector<int> edges;
	for (int i = 1; i <= N; ++ i) {
		for (auto n : listN[i]) {
			int node = n.first;
			if (cap[i][node] == flow[i][node]) {
				cost += n.second * flow[i][node];
				edges.push_back(edgeIndex[i][node]);
			}
		}
	}
	
	std::ofstream out("cmcm.out");
	
	out << edges.size() << " " << cost << "\n";
	for(auto e : edges) {
		out << e << " ";
	}
	out << "\n";
	
	out.close();
	
	return 0;
}