Problem p01794 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
#define FOR(i, a, b) for (int i = (a); i < (int)(b); i++)
#define rep(i, a) FOR(i, 0, a)
#define all(a) (a).begin(), (a).end()
#define pb push_back
#define sz size()
#define MP make_pair
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;

const static ll INF = 1e18;

struct edge {
  ll from, to, cost, cap, rev;
  edge(ll a, ll b, ll c, ll d, ll e)
      : from(a), to(b), cost(c), cap(d), rev(e) {}
};

// Based on Dijkstra (using potential)
struct minFlow {
  ll v;
  vector<vector<edge>> graph;
  vll d, use, h, pv, pe;

  minFlow(ll n) : v(n) {
    graph = vector<vector<edge>>(n);
    pv.resize(v);
    pe.resize(v);
  }

  void add(ll s, ll g, ll c, ll p) {
    graph[s].pb(edge(s, g, c, p, graph[g].sz));
    graph[g].pb(edge(g, s, -c, 0, graph[s].sz - 1));
  }

  void cal(ll s, ll t, vll &w, vll &b, vll &x) {
    ll cost = 0, flow = 0;
    x.pb(0);

    h = vll(v, 0);
    while (1) {
      priority_queue<pll, vector<pll>, greater<pll>> q;
      d = vll(v, INF);
      d[s] = 0;
      q.push(MP(0, s));
      while (q.sz) {
        pll p = q.top();
        q.pop();
        ll u = p.second;
        if (d[u] < p.first)
          continue;
        rep(i, graph[u].sz) {
          edge &e = graph[u][i];
          if (e.cap > 0 && d[e.to] > d[u] + e.cost + h[u] - h[e.to]) {
            d[e.to] = d[u] + e.cost + h[u] - h[e.to];
            pv[e.to] = u;
            pe[e.to] = i;
            q.push(MP(d[e.to], e.to));
          }
        }
      }
      if (d[t] == INF)
        return;
      rep(u, v) h[u] += d[u];

      ll f = INF;
      for (int u = t; u != s; u = pv[u])
        f = min(f, graph[pv[u]][pe[u]].cap);
      flow += f;

      w.pb(h[t]);
      b.pb(cost);
      x.pb(flow);

      cost += f * h[t];

      for (int u = t; u != s; u = pv[u]) {
        edge &e = graph[pv[u]][pe[u]];
        e.cap -= f;
        graph[u][e.rev].cap += f;
      }
    }
  }
};

bool Less(ll u1, ll d1, ll u2, ll d2) {
  // u1/d1 < u2/d2
  ll p1 = u1 / d1, q1 = u1 % d1, p2 = u2 / d2, q2 = u2 % d2;
  if (p1 != p2)
    return p1 < p2;
  return q1 * d2 < q2 * d1;
}

int main() {
  ll n, m, s, t;
  scanf("%lld %lld %lld %lld", &n, &m, &s, &t);
  s--;
  t--;
  minFlow mf(n);
  rep(i, m) {
    ll a, b, u, c;
    scanf("%lld %lld %lld %lld", &a, &b, &u, &c);
    a--;
    b--;
    mf.add(a, b, c, u);
  }

  vector<ll> a, b, x;
  mf.cal(s, t, a, b, x);
  ll M = x.back();

  ll ansu = INF, ansd = 1;
  rep(i, b.size()) {
    ll b1 = b[i], f1 = M - x[i];
    ansu = min(ansu, b1 * b1 + f1 * f1);
    ll b2 = b[i] + a[i] * (x[i + 1] - x[i]), f2 = M - x[i + 1];
    ansu = min(ansu, b2 * b2 + f2 * f2);
    cerr << b2 * b2 + f2 * f2 << endl;
  }

  rep(i, b.size()) {
    ll xu = M - a[i] * b[i] + a[i] * a[i] * x[i], xd = a[i] * a[i] + 1;
    if (Less(xu, xd, x[i], 1) || Less(x[i + 1], 1, xu, xd))
      continue;

    ll tmpu = (a[i] * M + b[i] - a[i] * x[i]) * (a[i] * M + b[i] - a[i] * x[i]),
       tmpd = xd;
    if (Less(tmpu, tmpd, ansu, ansd)) {
      ansu = tmpu;
      ansd = tmpd;
    }
  }

  if (a.empty()) {
    ansu = 0;
    ansd = 1;
  }

  ll gcd = __gcd(ansu, ansd);
  printf("%lld/%lld\n", ansu / gcd, ansd / gcd);
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
#define FOR(i, a, b) for (int i = (a); i < (int)(b); i++)
#define rep(i, a) FOR(i, 0, a)
#define all(a) (a).begin(), (a).end()
#define pb push_back
#define sz size()
#define MP make_pair
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;

const static ll INF = 1e18;

struct edge {
  ll from, to, cost, cap, rev;
  edge(ll a, ll b, ll c, ll d, ll e)
      : from(a), to(b), cost(c), cap(d), rev(e) {}
};

// Based on Dijkstra (using potential)
struct minFlow {
  ll v;
  vector<vector<edge>> graph;
  vll d, use, h, pv, pe;

  minFlow(ll n) : v(n) {
    graph = vector<vector<edge>>(n);
    pv.resize(v);
    pe.resize(v);
  }

  void add(ll s, ll g, ll c, ll p) {
    graph[s].pb(edge(s, g, c, p, graph[g].sz));
    graph[g].pb(edge(g, s, -c, 0, graph[s].sz - 1));
  }

  void cal(ll s, ll t, vll &w, vll &b, vll &x) {
    ll cost = 0, flow = 0;
    x.pb(0);

    h = vll(v, 0);
    while (1) {
      priority_queue<pll, vector<pll>, greater<pll>> q;
      d = vll(v, INF);
      d[s] = 0;
      q.push(MP(0, s));
      while (q.sz) {
        pll p = q.top();
        q.pop();
        ll u = p.second;
        if (d[u] < p.first)
          continue;
        rep(i, graph[u].sz) {
          edge &e = graph[u][i];
          if (e.cap > 0 && d[e.to] > d[u] + e.cost + h[u] - h[e.to]) {
            d[e.to] = d[u] + e.cost + h[u] - h[e.to];
            pv[e.to] = u;
            pe[e.to] = i;
            q.push(MP(d[e.to], e.to));
          }
        }
      }
      if (d[t] == INF)
        return;
      rep(u, v) h[u] += d[u];

      ll f = INF;
      for (int u = t; u != s; u = pv[u])
        f = min(f, graph[pv[u]][pe[u]].cap);
      flow += f;

      w.pb(h[t]);
      b.pb(cost);
      x.pb(flow);

      cost += f * h[t];

      for (int u = t; u != s; u = pv[u]) {
        edge &e = graph[pv[u]][pe[u]];
        e.cap -= f;
        graph[u][e.rev].cap += f;
      }
    }
  }
};

bool Less(ll u1, ll d1, ll u2, ll d2) {
  // u1/d1 < u2/d2
  ll p1 = u1 / d1, q1 = u1 % d1, p2 = u2 / d2, q2 = u2 % d2;
  if (p1 != p2)
    return p1 < p2;
  return q1 * d2 < q2 * d1;
}

int main() {
  ll n, m, s, t;
  scanf("%lld %lld %lld %lld", &n, &m, &s, &t);
  s--;
  t--;
  minFlow mf(n);
  rep(i, m) {
    ll a, b, u, c;
    scanf("%lld %lld %lld %lld", &a, &b, &u, &c);
    a--;
    b--;
    mf.add(a, b, c, u);
  }

  vector<ll> a, b, x;
  mf.cal(s, t, a, b, x);
  ll M = x.back();

  ll ansu = INF, ansd = 1;
  rep(i, b.size()) {
    ll b1 = b[i], f1 = M - x[i];
    ansu = min(ansu, b1 * b1 + f1 * f1);
    ll b2 = b[i] + a[i] * (x[i + 1] - x[i]), f2 = M - x[i + 1];
    ansu = min(ansu, b2 * b2 + f2 * f2);
  }

  rep(i, b.size()) {
    ll xu = M - a[i] * b[i] + a[i] * a[i] * x[i], xd = a[i] * a[i] + 1;
    if (Less(xu, xd, x[i], 1) || Less(x[i + 1], 1, xu, xd))
      continue;

    ll tmpu = (a[i] * M + b[i] - a[i] * x[i]) * (a[i] * M + b[i] - a[i] * x[i]),
       tmpd = xd;
    if (Less(tmpu, tmpd, ansu, ansd)) {
      ansu = tmpu;
      ansd = tmpd;
    }
  }

  if (a.empty()) {
    ansu = 0;
    ansd = 1;
  }

  ll gcd = __gcd(ansu, ansd);
  printf("%lld/%lld\n", ansu / gcd, ansd / gcd);
}