Pagini recente » Cod sursa (job #468812) | Cod sursa (job #1803506) | Cod sursa (job #297444) | Cod sursa (job #1970564) | Cod sursa (job #2696859)
#ifdef LOCAL
#include <debug.hpp>
#else
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,tune=native")
#define debug(...)
#endif
#include <bits/stdc++.h>
using namespace std;
template<typename T>
pair<T, vector<int>> MinAssignment(const vector<vector<T>> &W) {
int n = W.size(), m = W[0].size(); // assert(n <= m);
vector<T> v(m), dist(m); // v: potential
vector<int> L(n, -1), R(m, -1); // matching pairs
vector<int> index(m), prev(m);
iota(index.begin(), index.end(), 0);
auto residue = [&](int i, int j) { return W[i][j] - v[j]; };
for (int f = 0; f < n; ++f) {
for (int j = 0; j < m; ++j)
dist[j] = residue(f, j), prev[j] = f;
T w; int j, l, s = 0, t = 0;
while (true) {
if (s == t) {
l = s; w = dist[index[t++]];
for (int k = t; k < m; ++k) {
j = index[k]; T h = dist[j];
if (h <= w) {
if (h < w) t = s, w = h;
index[k] = index[t]; index[t++] = j;
}
}
for (int k = s; k < t; ++k) {
j = index[k];
if (R[j] < 0) goto aug;
}
}
int q = index[s++], i = R[q];
for (int k = t; k < m; ++k) {
j = index[k];
T h = residue(i, j) - residue(i, q) + w;
if (h < dist[j]) {
dist[j] = h; prev[j] = i;
if (h == w) {
if (R[j] < 0) goto aug;
index[k] = index[t]; index[t++] = j;
}
}
}
}
aug:
for(int k = 0; k < l; ++k)
v[index[k]] += dist[index[k]] - w;
int i;
do {
R[j] = i = prev[j];
swap(j, L[i]);
} while (i != f);
}
T ret = 0;
for (int i = 0; i < n; ++i)
ret += W[i][L[i]]; // (i, L[i]) is a solution
return {ret, L};
}
int main() {
ifstream cin("cmcm.in");
ofstream cout("cmcm.out");
int n, m, e; cin >> n >> m >> e; m = max(n, m);
const int INF = 5e6;
vector<vector<int>> W(n, vector<int>(m, INF));
vector<vector<int>> I(n, vector<int>(m, -1));
for (int i = 0; i < e; ++i) {
int a, b, c; cin >> a >> b >> c; --a; --b;
if (W[a][b] > c) W[a][b] = c, I[a][b] = i;
}
int ans; vector<int> L;
tie(ans, L) = MinAssignment(W);
vector<int> es;
for (int i = 0; i < n; ++i)
if (I[i][L[i]] != -1)
es.push_back(I[i][L[i]]);
else
ans -= INF;
cout << es.size() << " " << ans << endl;
for (auto i : es) cout << i + 1 << " "; cout << endl;
return 0;
}