Cod sursa(job #2476028)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 17 octombrie 2019 22:03:12
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.16 kb
#include <bits/stdc++.h>
using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define dbg(x) cerr<<#x": "<<(x)<<endl
#define dbg_p(x) cerr<<#x": "<<(x).first<<' '<<(x).second<<endl
#define dbg_v(x, n) {cerr<<#x"[]: ";for(long long _=0;_<n;++_)cerr<<(x)[_]<<' ';cerr<<endl;}
#define all(v) v.begin(), v.end()
#define fi first
#define se second

template<typename T1, typename T2>
ostream& operator <<(ostream &out, const pair<T1, T2> &item) {
	out << '(' << item.first << ", " << item.second << ')';
	return out;
}

template <typename T>
ostream& operator <<(ostream &out, const vector<T>& v) {
	for(const auto &item : v) out << item << ' ';
	return out;
}

const int N = 610;
const int SOURCE = 0;
const int SINK = N - 1;
const int INF = 0x3f3f3f3f;

struct Edge {
	int to, flow, cst, id;
};

int d[N], newd[N], reald[N], prv[N];
bool vis[N];
vector<int> adj[N];
vector<Edge> edges;

void addEdge(int a, int b, int cap, int cst, int id) {
	adj[a].push_back(edges.size());
	edges.push_back({b, cap, cst, id});
	
	adj[b].push_back(edges.size());
	edges.push_back({a, 0, -cst, -1});
}

void bellman() {
	memset(d, INF, sizeof d);
	
	priority_queue<pii> q;
	for(d[SOURCE] = 0, q.push({0, SOURCE}); !q.empty(); ) {
		int dst = -q.top().fi;
		int v = q.top().se;
		q.pop();
		
		if(dst != d[v]) continue;
		
		for(auto id : adj[v]) {
			int u = edges[id].to;
			if(edges[id].flow && d[u] > d[v] + edges[id].cst) {
				d[u] = d[v] + edges[id].cst;
				q.push({-d[u], u});
			}
		}
	}
}

bool dijkstra() {
	memset(newd, INF, sizeof newd);
	memset(vis, 0, sizeof vis);
	
	priority_queue<pii> q;
	for(newd[SOURCE] = reald[SOURCE] = 0, q.push({0, SOURCE}); !q.empty(); ) {
		int dst = -q.top().fi;
		int v = q.top().se;
		q.pop();
		
		if(vis[v]) continue;
		vis[v] = true;
		
		for(auto id : adj[v]) {
			int u = edges[id].to;
			int w = d[v] + edges[id].cst - d[u];
			if(edges[id].flow && newd[u] > newd[v] + w) {
				newd[u] = newd[v] + w;
				reald[u] = reald[v] + edges[id].cst;
				prv[u] = id;
				q.push({-newd[u], u});
			}
		}
	}
	
	return newd[SINK] < INF;
}

pii mcmf() {
	int flow, cst, pushed, v;
	
	bellman();
	for(flow = cst = 0; dijkstra(); ) {
		for(pushed = INF, v = SINK; v != SOURCE; v = edges[prv[v] ^ 1].to) {
			pushed = min(pushed, edges[prv[v]].flow);
		}
		
		flow += pushed;
		for(v = SINK; v != SOURCE; v = edges[prv[v] ^ 1].to) {
			cst += pushed * edges[prv[v]].cst;
			edges[prv[v]].flow -= pushed;
			edges[prv[v] ^ 1].flow += pushed;
		}
		
		memcpy(d, reald, sizeof reald);
	}
	
	return { flow, cst };
}

int main()
{
	ios_base::sync_with_stdio(false);
	freopen("cmcm.in", "r", stdin);
	freopen("cmcm.out", "w", stdout);
	
	int n, m, e, a, b, c;
	
	cin >> n >> m >> e;
	for(int i = 1; i <= e; ++i) {
		cin >> a >> b >> c;
		addEdge(a, b + n, 1, c, i);
	}
	
	for(int i = 1; i <= n; ++i) addEdge(SOURCE, i, 1, 0, -1);
	for(int i = 1; i <= m; ++i) addEdge(i + n, SINK, 1, 0, -1);
	
	pii ret = mcmf();
	
	cout << ret.fi << ' ' << ret.se << '\n';
	for(int i = 1; i <= n; ++i)
		for(auto id : adj[i]) {
			if(edges[id].id > 0 && !edges[id].flow) cout << edges[id].id << ' ';
		}
	
	cout << '\n';
	
	return 0;
}