Cod sursa(job #2889117)

Utilizator andrei_C1Andrei Chertes andrei_C1 Data 12 aprilie 2022 12:01:25
Problema Cuplaj maxim de cost minim Scor 80
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.32 kb
#include <bits/stdc++.h>

using namespace std;

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

const int INF = 1e9;

int n, m, e, ans, cost, s, d;
vector<bool> inQ;
vector<int> dist, parent;
vector<pair<int, int>> edges;
vector<vector<pair<int, int>>> adj;
vector<vector<int>> capacity, flow;

bool bf(int s, int d) {
	parent = vector<int> (n + m + 2, -1);
	inQ = vector<bool> (n + m + 2, 0);
	dist = vector<int> (n + m + 2, INF);
	queue<int> q;

	q.push(s);
	inQ[s] = 1;
	dist[s] = 0;

	while(!q.empty()) {
		int node = q.front();
		q.pop();
		inQ[node] = 0;

		for(auto it: adj[node]) {
			if(flow[node][it.first] == capacity[node][it.first]) {
				continue;
			}

			if(dist[it.first] > dist[node] + it.second) {
				dist[it.first] = dist[node] + it.second;
				parent[it.first] = node;

				if(!inQ[it.first]) {
					q.push(it.first);
					inQ[it.first] = 1;
				}
			}
		}
	}

	return dist[d] != INF;
}

int main() {
	fin >> n >> m >> e;

	adj = vector<vector<pair<int, int>>> (n + m + 2);
	capacity = vector<vector<int>> (n + m + 2, vector<int> (n + m + 2, 0));
	flow = vector<vector<int>> (n + m + 2, vector<int> (n + m + 2, 0));

	for(int i = 1; i <= e; i++) {
		int p, q, c;
		fin >> p >> q >> c;

		q += n;

		// cout << p << " " << q << " " << c << '\n';

		capacity[p][q] = 1;
		edges.push_back({p, q});
		adj[p].push_back({q, c});
		adj[q].push_back({p, -c});
	}

	s = 0;
	d = n + m + 1;

	for(int node = 1; node <= n; node++) {
		capacity[s][node] = 1;
		adj[s].push_back({node, 0});
		adj[node].push_back({s, 0});
	}

	for(int node = n + 1; node <= n + m + 1; node++) {
		capacity[node][d] = 1;
		adj[node].push_back({d, 0});
		adj[d].push_back({node, 0});
	}

	while(bf(s, d)) {
		int maxflow = INF;

		for(int p = d; p != s; p = parent[p]) {
			if(maxflow == 0) {
				continue;
			}
			
			maxflow = min(maxflow, capacity[parent[p]][p] - flow[parent[p]][p]);
		}

		for(int p = d; p != s; p = parent[p]) {
			flow[p][parent[p]] -= maxflow;
			flow[parent[p]][p] += maxflow;
		}

		// cout << maxflow << " " << dist[d] << " => ";
		// for(int p = d; p != s; p = parent[p]) {
		// 	cout << p << " ";
		// }
		// cout << '\n';

		ans += maxflow;
		cost += maxflow * dist[d];
	}

	fout << ans << " " << cost << '\n';
	for(int i = 0; i < (int) edges.size(); i++) {
		if(flow[edges[i].first][edges[i].second] == 1) {
			fout << i + 1 << " ";
		}
	}
	return 0;
}