Cod sursa(job #2882888)

Utilizator Alex_tz307Lorintz Alexandru Alex_tz307 Data 31 martie 2022 21:34:56
Problema Cuplaj maxim de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.31 kb
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f

using namespace std;

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

map<pair<int, int>, int> idx;

void minSelf(int &x, int y) {
  if (y < x) {
    x = y;
  }
}

struct MCMF {
  int n, s, t, maxFlow = 0;
  int64_t minCost = 0;
  vector<vector<int>> g, C, W;
  vector<int> d, dp, par;
  vector<bool> inQ;

  MCMF(int _n, int _s, int _t) : n(_n), s(_s), t(_t) {
    g.resize(n + 1);
    C.resize(n + 1, vector<int>(n + 1));
    W.resize(n + 1, vector<int>(n + 1));
    d.resize(n + 1, INF);
    dp.resize(n + 1);
    par.resize(n + 1);
    inQ.resize(n + 1);
  }

  void addEdge(int u, int v, int c, int w) {
    g[u].emplace_back(v);
    g[v].emplace_back(u);
    C[u][v] += c;
    W[u][v] = w;
    W[v][u] = -w;
  }

  void BellmanFord() {
    d[s] = 0;
    queue<int> q;
    q.emplace(s);
    inQ[s] = true;
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      inQ[u] = false;
      for (int v : g[u]) {
        if (C[u][v] && d[v] > d[u] + W[u][v]) {
          d[v] = d[u] + W[u][v];
          if (!inQ[v]) {
            q.emplace(v);
            inQ[v] = true;
          }
        }
      }
    }
  }

  bool Dijkstra() {
    for (int i = 1; i <= n; ++i) {
      dp[i] = INF;
    }
    dp[s] = 0;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    pq.emplace(0, s);
    while (!pq.empty()) {
      int cost, u;
      tie(cost, u) = pq.top();
      pq.pop();
      if (cost != dp[u]) {
        continue;
      }
      for (int v : g[u]) {
        if (C[u][v] == 0) {
          continue;
        }
        int newCost = cost + W[u][v] + d[u] - d[v];
        if (newCost < dp[v]) {
          dp[v] = newCost;
          par[v] = u;
          if (v != t) {
            pq.emplace(newCost, v);
          }
        }
      }
    }
    if (dp[t] == INF) {
      return false;
    }
    int flow = INF;
    for (int v = t; v != s; v = par[v]) {
      minSelf(flow, C[par[v]][v]);
      if (flow == 0) {
        return false;
      }
    }
    maxFlow += flow;
    minCost += (int64_t)flow * (dp[t] - d[s] + d[t]);
    for (int v = t; v != s; v = par[v]) {
      C[par[v]][v] -= flow;
      C[v][par[v]] += flow;
    }
    return true;
  }

  pair<int, int64_t> solve() {
    BellmanFord();
    while (Dijkstra());
    return {maxFlow, minCost};
  }

  void printEdges(int N) {
    for (int i = 2; i <= N + 1; ++i) {
      for (int j = N + 2; j < n; ++j) {
        if (C[i][j] == 0 && idx.count({i, j})) {
          fout << idx[{i, j}] + 1 << ' ';
        }
      }
    }
    fout << '\n';
  }
};

void testCase() {
  int n, m, E;
  fin >> n >> m >> E;
  int s = 1, t = n + m + 2;
  MCMF g(t, s, t);
  for (int i = 2; i <= n + 1; ++i) {
    g.addEdge(s, i, 1, 0);
  }
  for (int i = n + 2; i <= n + m + 1; ++i) {
    g.addEdge(i, t, 1, 0);
  }
  for (int i = 0; i < E; ++i) {
    int u, v, w;
    fin >> u >> v >>  w;
    g.addEdge(u + 1, v + n + 1, 1, w);
    idx[{u, v}] = i;
  }
  pair<int, int64_t> res = g.solve();
  fout << res.first << ' ' << res.second << '\n';
  g.printEdges(n);
}

int main() {
  int tests = 1;
  for (int tc = 0; tc < tests; ++tc) {
    testCase();
  }
  fin.close();
  fout.close();
  return 0;
}