Cod sursa(job #2557478)

Utilizator Robert_VRVRobert Vadastreanu Robert_VRV Data 25 februarie 2020 20:28:07
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.07 kb
#include <fstream>
#include <queue>
#include <vector>

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

const int MAX_N = 605;
const int INF = 1e9;

std::vector<int> G[MAX_N];
int r[MAX_N][MAX_N];
int father[MAX_N];
int cost[MAX_N][MAX_N];
int index[MAX_N][MAX_N];

int dist[MAX_N];
bool inQ[MAX_N];
int flow[MAX_N];

bool bellman_ford(int S, int D) {
  for (int i = S; i <= D; i++) {
    dist[i] = INF;
    flow[i] = INF;
  }
  std::queue<int> q;
  q.push(S);
  inQ[S] = true;
  dist[S] = 0;
  while (!q.empty()) {
    int node = q.front();
    q.pop();
    inQ[node] = false;
    for (int u : G[node])
      if (r[node][u] > 0 && dist[u] > dist[node] + cost[node][u]) {
        dist[u] = dist[node] + cost[node][u];
        father[u] = node;
        flow[u] = std::min(flow[node], r[node][u]);
        if (!inQ[u]) {
          q.push(u);
          inQ[u] = true;
        }
      }
  }
  return dist[D] != INF;
}

int main() {

  int n1, n2, m;
  fin >> n1 >> n2 >> m;
  for (int i = 1; i <= m; i++) {
    int u, v, cst;
    fin >> u >> v >> cst;
    v += n1;
    index[u][v] = i;
    index[v][u] = i;
    G[u].push_back(v);
    G[v].push_back(u);
    r[u][v] = 1;
    cost[u][v] = cst;
    cost[v][u] = -cst;
  }
  int S = 0, D = n1 + n2 + 1;
  for (int i = 1; i <= n1; i++) {
    G[S].push_back(i);
    G[i].push_back(S);
    r[S][i] = 1;
    cost[S][i] = 0;
    cost[i][S] = 0;
  }
  for (int i = n1 + 1; i < D; i++) {
    G[i].push_back(D);
    G[D].push_back(i);
    r[i][D] = 1;
    cost[i][D] = 0;
    cost[D][i] = 0;
  }

  int maxFlow = 0, minCost = 0;
  while (bellman_ford(S, D)) {
    for (int i = D; i != S; i = father[i]) {
      r[father[i]][i] -= flow[D];
      r[i][father[i]] += flow[D];
    }
    minCost += flow[D] * dist[D];
    maxFlow += flow[D];
  }
  fout << maxFlow << " " << minCost << '\n';
  for (int i = 1; i <= n1; i++)
    for (int j = 1; j <= n2; j++)
      if (r[i][j + n1] == 0 && index[i][j + n1] != 0)
        fout << index[i][j + n1] << " ";
  fout << '\n';

  return 0;
}