Cod sursa(job #2695699)

Utilizator Stefan_RaduStefan Radu Stefan_Radu Data 14 ianuarie 2021 11:53:30
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.36 kb
// By Stefan Radu

#include <bits/stdc++.h>

using namespace std;

#define sz(x) (int)(x).size()

typedef pair < int, int > pii;
typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef unsigned long long ull;

const int INF = 2e9;

struct Edge {
  int node, cost;
};

int n, m, k, source, sink;
int cap[602][602];
int flow[602][602];
int ind[602][602];
int tata[602], dist[602];
bool inq[602];

vector < vector < Edge > > gr;
int cuplaj = 0;

int bellman() {

  queue < int > q;
  for (int i = 0; i < n + m + 2; ++ i) {
    dist[i] = INF;
    inq[i] = false;
  }

  q.push(source);
  dist[source] = 0;
  inq[source] = true;

  while (!q.empty()) {

    int currNode = q.front();
    inq[currNode] = false;
    q.pop();

    for (auto &nei : gr[currNode]) {
      if (flow[currNode][nei.node] < cap[currNode][nei.node] &&
          dist[nei.node] > dist[currNode] + nei.cost) {

        tata[nei.node] = currNode;
        dist[nei.node] = dist[currNode] + nei.cost;
        if (!inq[nei.node]) {
          inq[nei.node] = true;
          q.push(nei.node);
        }
      }
    }
  }

  if (dist[sink] != INF) {
    int f = INF;

    for (int node = sink; node != source; node = tata[node]) {
      f = min(f, cap[tata[node]][node] - flow[tata[node]][node]);
    }

    if (f == 0) return 0;

    for (int node = sink; node != source; node = tata[node]) {
      flow[tata[node]][node] += f;
      flow[node][tata[node]] -= f;
    }

    cuplaj += f;
    return f * dist[sink];
  }

  return 0;
}

int main() {

  ifstream fin("cmcm.in");
  fin >> n >> m >> k;

  source = 0;
  sink = n + m + 1;

  gr.resize(n + m + 2);

  for (int i = 0; i < k; ++ i) {
    int a, b, c;
    fin >> a >> b >> c;
    gr[a].push_back({n + b, c});
    gr[n + b].push_back({a, -c});
    cap[a][n + b] = 1;
    cap[a][n + b] = 1;
    ind[a][n + b] = i + 1;
  }

  for (int i = 1; i <= n; ++ i) {
    gr[source].push_back({i, 0});
    cap[source][i] = 1;
  }

  for (int i = n + 1; i <= n + m; ++ i) {
    gr[i].push_back({sink, 0});
    cap[i][sink] = 1;
  }

  int sol = 0, augument = 1;
  while (augument) {
    augument = bellman();
    sol += augument;
  }

  ofstream fout("cmcm.out");
  fout << cuplaj << ' ' << sol << '\n';
  for (int i = 1; i <= n; ++ i) {
    for (int j = n + 1; j <= n + m; ++ j) {
      if (cap[i][j] && flow[i][j]) {
        fout << ind[i][j] << ' ';
        break;
      }
    }
  }
}