Cod sursa(job #2691547)

Utilizator retrogradLucian Bicsi retrograd Data 29 decembrie 2020 11:40:18
Problema Flux maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.57 kb
#include <bits/stdc++.h>

using namespace std;

using T = double; // long double, Rational, double + mod<P>...
using vec = vector<T>;
using mat = vector<vec>;

const T EPS = 1e-8, INF = 1/.0;
#define MP make_pair
#define LTJ(X) if(s == -1 || MP(X[j],N[j]) < MP(X[s],N[s])) s=j
#define FOR(i, a, b) for(int i = a; i < (b); ++i)

double Simplex(mat A, vec b, vec c, vec& x) {
  int m = b.size(), n = c.size();
  vector<int> N(n + 1), B(m);
  mat D(m + 2, vec(n + 2));

  FOR (i, 0, m) FOR (j, 0, n) D[i][j] = A[i][j];
  FOR (i, 0, m) B[i] = n + i, D[i][n] = -1, D[i][n + 1] = b[i];
  FOR (j, 0, n) N[j] = j, D[m][j] = -c[j];
  N[n] = -1, D[m + 1][n] = 1;

  auto pivot = [&](int r, int s) {
    vec& a = D[r]; T inv = 1. / a[s];
    FOR (i, 0, m + 2) if (i != r && abs(D[i][s]) > EPS) {
      vec& b = D[i]; T inv2 = b[s] * inv;
      FOR (j, 0, n + 2) b[j] -= a[j] * inv2;
      b[s] = a[s] * inv2;
    }
    FOR (j, 0, n + 2) if (j != s) D[r][j] *= inv;
    FOR (i, 0, m + 2) if (i != r) D[i][s] *= -inv;
    D[r][s] = inv;
    swap(B[r], N[s]);
  };
  auto simplex = [&](int phase) {
    int x = m + phase - 1;
    while (true) {
      int s = -1;
      FOR (j, 0, n + 1) if (N[j] != -phase) LTJ(D[x]);
      if (D[x][s] > -EPS) return true;
      int r = -1;
      FOR (i, 0, m) {
        if (D[i][s] < EPS) continue;
        if (r == -1 || MP(D[i][n + 1] / D[i][s], B[i])
                     < MP(D[r][n + 1] / D[r][s], B[r])) r = i;
      }
      if (r == -1) return false;
      pivot(r, s);
    }
  };
  int r = 0;
  FOR (i, 1, m) if (D[i][n + 1] < D[r][n + 1]) r = i;
  if (D[r][n + 1] < -EPS) {
    pivot(r, n);
    if (!simplex(2) || D[m + 1][n + 1] < -EPS) return -INF;
    FOR (i, 0, m) if (B[i] == -1) {
      int s = 0;
      FOR (j, 1, n + 1) LTJ(D[i]);
      pivot(i, s);
    }
  }
  bool ok = simplex(1); x.assign(n, 0);
  FOR (i, 0, m) if (B[i] < n) x[B[i]] = D[i][n + 1];
  return ok ? D[m][n + 1] : INF;
}

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

  int n, m, s, t; cin >> n >> m >> s >> t; ++m;
  // min f[i][j] * k[i][j]
  // s.t. f[i][j] <= c[i][j]
  mat A(m + 2 * n, vec(m));
  vec b(m + 2 * n);
  vec c(m);
  auto add = [&](int i, int u, int v, int cap, int kost) {
    c[i] = kost;
    A[i][i] = 1; b[i] = cap;
    A[u + m][i] = -1; A[v + m][i] = +1;
    A[u + m + n][i] = +1; A[v + m + n][i] = -1;
  };
  add(0, t - 1, s - 1, 1e9, 1e9);
  for (int i = 1; i < m; ++i) {
    int a, b, c, k; cin >> a >> b >> c >> k;
    add(i, a - 1, b - 1, c, -k);
  }
  vec x;
  double ans = Simplex(A, b, c, x);
  ans -= 1e9 * x[0];
  cout << (long long)(round(-ans)) << endl;

  return 0;
}