Cod sursa(job #2716055)

Utilizator retrogradLucian Bicsi retrograd Data 4 martie 2021 17:26:38
Problema Cuplaj maxim de cost minim Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.16 kb
#include <bits/stdc++.h>

using namespace std;
using ll = int;
const ll INF = 2e9;

vector<int> MinAssignment(const vector<vector<ll>>& W) {
  int n = W.size(), m = W[0].size();       // assert(n <= m);
  vector<ll> v(m), dist(m);                // v: potential
  vector<int> L(n, -1), R(m, -1);          // matching pairs
  vector<int> idx(m), prev(m);
  iota(idx.begin(), idx.end(), 0);
  
  ll w; int j, l, s, t;
  auto residue = [&](int i, int j) { return W[i][j] - v[j]; };
  auto reduce = [&]() {
    if (s == t) {
      l = s; w = dist[idx[t++]];
      for (int k = t; k < m; ++k) {
        j = idx[k]; ll h = dist[j];
        if (h <= w) {
          if (h < w) t = s, w = h; 
          idx[k] = idx[t]; idx[t++] = j;
        }
      }
      for (int k = s; k < t; ++k) {
        j = idx[k]; 
        if (R[j] < 0) return 1;
      }
    }
    int q = idx[s++], p = R[q];
    for (int k = t; k < m; ++k) {
      j = idx[k];
      ll h = residue(p, j) - residue(p, q) + w;
      if (h < dist[j]) {
        dist[j] = h; prev[j] = p;
        if (h == w) {
          if (R[j] < 0) return 1;
          idx[k] = idx[t]; idx[t++] = j;
        }
      }
    }
    return 0;
  };
  for (int i = 0; i < n; ++i) {
    for (int k = 0; k < m; ++k) 
      dist[k] = residue(i, k), prev[k] = i;
    s = t = 0;
    while (!reduce());
    for (int k = 0; k < l; ++k) v[idx[k]] += dist[idx[k]] - w;
    for (int k = -1; k != i;) R[j] = k = prev[j], swap(j, L[k]);
  }
  ll ret = 0;
  for (int i = 0; i < n; ++i) 
    ret += W[i][L[i]]; // (i, L[i]) is a solution
  return L;
}

int main() {
  ifstream cin("cmcm.in");
  ofstream cout("cmcm.out");

  int n, m, e; cin >> n >> m >> e;
  m = max(n, m);
  vector<vector<ll>> W(n, vector<ll>(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;
    W[a - 1][b - 1] = c;
    I[a - 1][b - 1] = i;
  }
  ll cost = 0, flow = 0;
  auto L = MinAssignment(W);
  for (int i = 0; i < n; ++i) 
    if (I[i][L[i]] != -1) 
      cost += W[i][L[i]], flow += 1;
   
  cout << flow << " " << cost << endl;
  for (int i = 0; i < n; ++i) 
    if (I[i][L[i]] != -1) 
      cout << I[i][L[i]] + 1 << " ";
  cout << endl;
}