Cod sursa(job #2696859)

Utilizator retrogradLucian Bicsi retrograd Data 16 ianuarie 2021 23:39:51
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.47 kb
#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;
}