Cod sursa(job #2670497)

Utilizator akumariaPatrascanu Andra-Maria akumaria Data 9 noiembrie 2020 23:26:28
Problema Cuplaj maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.54 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <utility>

using namespace std;
#define MAXN 302
#define INF 1<<30

int n, m, dest;

int edgeNo[MAXN][MAXN], cap[MAXN][MAXN], f[MAXN][MAXN];
int father[MAXN], used[MAXN], dist[MAXN];
vector<pair<int, int>> arcs[MAXN];


void addNodes() {
	for(int i=2; i<= n + 1; ++i) {
		arcs[1].push_back(pair<int, int>(i, 0));
		arcs[i].push_back(pair<int, int>(1, 0));
		cap[1][i] = 1;
	}

	for(int i= n + 2; i < dest; ++i) {
		arcs[dest].push_back(pair<int, int> (i, 0));
		arcs[i].push_back(pair<int, int>(dest, 0));
		cap[i][dest] = 1;
	}
}

int bellmanFord() {
	for(int i=1; i<=dest; ++i) {
		father[i] = -1;
		used[i] = false;
		dist[i] = INF;
	}

	dist[1] = 0;
	used[1] = true;
	int current_node, next_node, next_cost, flux;

	queue <int> q;
	q.push(1);
	while (q.size()) {
		current_node = q.front();
		q.pop();

		for(int i=0; i<arcs[current_node].size(); ++i) {
			next_node = arcs[current_node][i].first;
			next_cost = arcs[current_node][i].second;

			if (cap[current_node][next_node] > f[current_node][next_node] && dist[next_node] > dist[current_node] + next_cost) {
				dist[next_node] = dist[current_node] + next_cost;
				father[next_node] = current_node;

				if (! used[next_node]) {
					used[next_node] = true;
					q.push(next_node);
				}
			}
		}

		used[current_node] = false;
	}


	if (dist[dest] == INF)
		return 0;

	flux = INF;

	for(int i=dest; i > 1; i = father[i])
		if (flux > cap[father[i]][i] - f[father[i]][i])
			flux = cap[father[i]][i] - f[father[i]][i];

	for(int i=dest; i > 1; i = father[i]) {
		f[father[i]][i] += flux;
		f[i][father[i]] -= flux;
	}

	return flux * dist[dest];
}


int main() {
	freopen("cmcm.in", "r", stdin);
	freopen("cmcm.out", "w", stdout);

	int e, p, q, c;
	scanf("%d%d%d", &n, &m, &e);
	dest = n + m + 2;

	for(int i=1; i<=e; ++i) {
		scanf("%d%d%d", &p, &q, &c);
		p += 1;
		q += n+1;

		arcs[p].push_back(pair<int, int>(q, c));
		arcs[q].push_back(pair<int, int>(p, -c));

		edgeNo[p][q] = i;
		cap[p][q] = 1;
	}

	addNodes();

	int improved, sol = 0;
	do {
		improved = bellmanFord();
		sol += improved;
	} while (improved);


	int nrEdges = 0;
	for(int i=2; i<=n+1; ++i)
		for(int j = n +2; j<= n+ m + 1; ++j)
			if (cap[i][j] && f[i][j])
				++nrEdges;

	printf("%d %d\n", nrEdges, sol);

	for(int i=2; i<=n+1; ++i)
		for(int j = n +2; j<= n+ m + 1; ++j)
			if (cap[i][j] && f[i][j])
				printf("%d ", edgeNo[i][j]);

	printf("\n");
	return 0;
}