Problem p02377 (C++) — buggy submission, verdict: Time Limit Exceeded

#pragma GCC optimize("O3")
#pragma GCC target("avx")
#include "bits/stdc++.h" // define macro "/D__MAI"

using namespace std;
typedef long long int ll;

#define xprintf(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
#define debugv(v)                                                              \\
  {                                                                            \\
    printf("L%d %s > ", __LINE__, #v);                                         \\
    for (auto e : v) {                                                         \\
      cout << e << " ";                                                        \\
    }                                                                          \\
    cout << endl;                                                              \\
  }
#define debuga(m, w)                                                           \\
  {                                                                            \\
    printf("L%d %s > ", __LINE__, #m);                                         \\
    for (int x = 0; x < (w); x++) {                                            \\
      cout << (m)[x] << " ";                                                   \\
    }                                                                          \\
    cout << endl;                                                              \\
  }
#define debugaa(m, h, w)                                                       \\
  {                                                                            \\
    printf("L%d %s >\\n", __LINE__, #m);                                        \\
    for (int y = 0; y < (h); y++) {                                            \\
      for (int x = 0; x < (w); x++) {                                          \\
        cout << (m)[y][x] << " ";                                              \\
      }                                                                        \\
      cout << endl;                                                            \\
    }                                                                          \\
  }
#define ALL(v) (v).begin(), (v).end()
#define repeat(cnt, l) for (auto cnt = 0ll; (cnt) < (l); ++(cnt))
#define iterate(cnt, b, e) for (auto cnt = (b); (cnt) != (e); ++(cnt))
#define MD 1000000007ll
#define PI 3.1415926535897932384626433832795
#define EPS 1e-12
template <typename T1, typename T2>
ostream &operator<<(ostream &o, const pair<T1, T2> p) {
  o << "(" << p.first << ":" << p.second << ")";
  return o;
}
template <typename iterator>
inline size_t argmin(iterator begin, iterator end) {
  return distance(begin, min_element(begin, end));
}
template <typename iterator>
inline size_t argmax(iterator begin, iterator end) {
  return distance(begin, max_element(begin, end));
}
template <typename T> T &maxset(T &to, const T &val) {
  return to = max(to, val);
}
template <typename T> T &minset(T &to, const T &val) {
  return to = min(to, val);
}
void bye(string s, int code = 0) {
  cout << s << endl;
  exit(0);
}
mt19937_64 randdev(8901016);
inline ll rand_range(ll l, ll h) {
  return uniform_int_distribution<ll>(l, h)(randdev);
}

#ifdef __MAI
#define getchar_unlocked getchar
#define putchar_unlocked putchar
#endif
#ifdef __VSCC
#define getchar_unlocked _getchar_nolock
#define putchar_unlocked _putchar_nolock
#endif
namespace {
#define isvisiblechar(c) (0x21 <= (c) && (c) <= 0x7E)
class MaiScanner {
public:
  template <typename T> void input_integer(T &var) {
    var = 0;
    T sign = 1;
    int cc = getchar_unlocked();
    for (; cc < '0' || '9' < cc; cc = getchar_unlocked())
      if (cc == '-')
        sign = -1;
    for (; '0' <= cc && cc <= '9'; cc = getchar_unlocked())
      var = (var << 3) + (var << 1) + cc - '0';
    var = var * sign;
  }
  inline int c() { return getchar_unlocked(); }
  inline MaiScanner &operator>>(int &var) {
    input_integer<int>(var);
    return *this;
  }
  inline MaiScanner &operator>>(long long &var) {
    input_integer<long long>(var);
    return *this;
  }
  inline MaiScanner &operator>>(string &var) {
    int cc = getchar_unlocked();
    for (; !isvisiblechar(cc); cc = getchar_unlocked())
      ;
    for (; isvisiblechar(cc); cc = getchar_unlocked())
      var.push_back(cc);
    return *this;
  }
  template <typename IT> void in(IT begin, IT end) {
    for (auto it = begin; it != end; ++it)
      *this >> *it;
  }
};
} // namespace
MaiScanner scanner;

class Flow {
public:
  typedef int cap_t;
  size_t n;
  struct Arrow {
    int from, to;
    cap_t left;
    cap_t cap;

    Arrow(int from = 0, int to = 0, cap_t w = 1)
        : from(from), to(to), left(w), cap(w) {}
    bool operator<(const Arrow &a) const {
      return (left != a.left) ? left < a.left
                              : (left < a.left) | (cap < a.cap) |
                                    (from < a.from) | (to < a.to);
    }
    bool operator==(const Arrow &a) const {
      return (from == a.from) && (to == a.to) && (left == a.left) &&
             (cap == a.cap);
    }
  };
  vector<vector<int>> vertex_to;
  vector<vector<int>> vertex_from;
  vector<Arrow> arrows;

  Flow(int n) : n(n), vertex_to(n), vertex_from(n) {}

  void connect(int from, int to, cap_t left) {
    vertex_to[from].push_back(arrows.size()); // toto
    vertex_from[to].push_back(arrows.size()); // fromfrom
    arrows.emplace_back(from, to, left);
  }
};

Flow::cap_t minconstflow(Flow &graph, const vector<Flow::cap_t> &cost,
                         int i_source, int i_sink, Flow::cap_t flow,
                         Flow::cap_t inf) {

  Flow::cap_t total_cost = 0;
  vector<Flow::cap_t> ofs(graph.n); // potential
  vector<Flow::cap_t> dist(graph.n);
  vector<int> prev(graph.n);

  // static function<Flow::cap_t(int, Flow::cap_t)> _dfs = [&](int idx,
  // Flow::cap_t f) {
  //     if (idx == i_source) return f;
  //     for (int ei : graph.vertex_from[idx]) {
  //         auto& edge = graph.arrows[ei];
  //         if (dist[edge.to] == dist[edge.from] + cost[ei] + ofs[edge.from] -
  //         ofs[edge.to]) {
  //             f = _dfs(edge.from, min(f, edge.left));
  //             if (f > 0) {
  //                 edge.left -= f;
  //                 return f;
  //             }
  //         }
  //     }
  //     for (int ei : graph.vertex_to[idx]) {
  //         auto& edge = graph.arrows[ei];
  //         if (dist[edge.from] == dist[edge.to] - cost[ei] + ofs[edge.to] -
  //         ofs[edge.from]) {
  //             f = _dfs(edge.to, min(f, edge.cap - edge.left));
  //             if (f > 0) {
  //                 edge.left += f;
  //                 return f;
  //             }
  //         }
  //     }
  //     return 0;
  // };

  while (flow > 0) {
    fill(dist.begin(), dist.end(), inf);
    fill(prev.begin(), prev.end(), -1);
    priority_queue<pair<Flow::cap_t, int>> pq;
    pq.emplace(0, i_source);
    dist[i_source] = 0;
    while (!pq.empty()) {
      auto p = pq.top();
      pq.pop();
      int idx = p.second;
      if (dist[idx] < -p.first)
        continue;
      for (int ei : graph.vertex_to[idx]) {
        auto edge = graph.arrows[ei];
        if (0 < edge.left &&
            dist[idx] + cost[ei] + ofs[idx] - ofs[edge.to] < dist[edge.to]) {
          dist[edge.to] = dist[idx] + cost[ei] + ofs[idx] - ofs[edge.to];
          prev[edge.to] = ei;
          pq.emplace(-dist[edge.to], edge.to);
        }
      }
      for (int ei : graph.vertex_from[idx]) {
        auto edge = graph.arrows[ei];
        if (0 < edge.cap - edge.left &&
            dist[idx] - cost[ei] + ofs[idx] - ofs[edge.from] <
                dist[edge.from]) {
          dist[edge.from] = dist[idx] - cost[ei] + ofs[idx] - ofs[edge.from];
          prev[edge.from] = ei;
          pq.emplace(-dist[edge.from], edge.from);
        }
      }
    }
    if (dist[i_sink] == inf)
      return -1;
    for (int i = 0; i < graph.n; ++i)
      ofs[i] += dist[i];
    // Flow::cap_t z = _dfs(i_sink, flow);

    Flow::cap_t z = flow;
    for (int p = i_sink; p != i_source;) {
      auto &edge = graph.arrows[prev[p]];
      if (edge.to == p)
        minset(z, edge.left), p = edge.from;
      else
        minset(z, edge.cap - edge.left), p = edge.to;
    }
    for (int p = i_sink; p != i_source;) {
      auto &edge = graph.arrows[prev[p]];
      if (edge.to == p)
        edge.left -= z, total_cost += z * cost[prev[p]], p = edge.from;
      else
        edge.left += z, total_cost -= z * cost[prev[p]], p = edge.to;
    }
    flow -= z;
    // total_cost += z * ofs[i_sink];
  }

  return total_cost;
}

ll m, n, kei;

int main() {
  ll f;
  scanner >> n >> m >> f;

  Flow graph(n);

  vector<int> cost(m);

  repeat(i, m) {
    int u, v, c, d;
    scanner >> u >> v >> c >> d;
    graph.connect(u, v, c);
    cost[i] = d;
  }

  auto ans = minconstflow(graph, cost, 0, n - 1, f, (ll)1e8);

  // for (auto e : graph.arrows){
  //     printf("%d->%d %d/%d\\n", e.from, e.to, e.cap-e.left, e.cap);
  // }

  cout << ans << endl;

  return 0;
}

Error: TLE

Fixed submission:

#pragma GCC optimize("O3")
#pragma GCC target("avx")
#include "bits/stdc++.h" // define macro "/D__MAI"

using namespace std;
typedef long long int ll;

#define xprintf(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
#define debugv(v)                                                              \\
  {                                                                            \\
    printf("L%d %s > ", __LINE__, #v);                                         \\
    for (auto e : v) {                                                         \\
      cout << e << " ";                                                        \\
    }                                                                          \\
    cout << endl;                                                              \\
  }
#define debuga(m, w)                                                           \\
  {                                                                            \\
    printf("L%d %s > ", __LINE__, #m);                                         \\
    for (int x = 0; x < (w); x++) {                                            \\
      cout << (m)[x] << " ";                                                   \\
    }                                                                          \\
    cout << endl;                                                              \\
  }
#define debugaa(m, h, w)                                                       \\
  {                                                                            \\
    printf("L%d %s >\\n", __LINE__, #m);                                        \\
    for (int y = 0; y < (h); y++) {                                            \\
      for (int x = 0; x < (w); x++) {                                          \\
        cout << (m)[y][x] << " ";                                              \\
      }                                                                        \\
      cout << endl;                                                            \\
    }                                                                          \\
  }
#define ALL(v) (v).begin(), (v).end()
#define repeat(cnt, l) for (auto cnt = 0ll; (cnt) < (l); ++(cnt))
#define iterate(cnt, b, e) for (auto cnt = (b); (cnt) != (e); ++(cnt))
#define MD 1000000007ll
#define PI 3.1415926535897932384626433832795
#define EPS 1e-12
template <typename T1, typename T2>
ostream &operator<<(ostream &o, const pair<T1, T2> p) {
  o << "(" << p.first << ":" << p.second << ")";
  return o;
}
template <typename iterator>
inline size_t argmin(iterator begin, iterator end) {
  return distance(begin, min_element(begin, end));
}
template <typename iterator>
inline size_t argmax(iterator begin, iterator end) {
  return distance(begin, max_element(begin, end));
}
template <typename T> T &maxset(T &to, const T &val) {
  return to = max(to, val);
}
template <typename T> T &minset(T &to, const T &val) {
  return to = min(to, val);
}
void bye(string s, int code = 0) {
  cout << s << endl;
  exit(0);
}
mt19937_64 randdev(8901016);
inline ll rand_range(ll l, ll h) {
  return uniform_int_distribution<ll>(l, h)(randdev);
}

#ifdef __MAI
#define getchar_unlocked getchar
#define putchar_unlocked putchar
#endif
#ifdef __VSCC
#define getchar_unlocked _getchar_nolock
#define putchar_unlocked _putchar_nolock
#endif
namespace {
#define isvisiblechar(c) (0x21 <= (c) && (c) <= 0x7E)
class MaiScanner {
public:
  template <typename T> void input_integer(T &var) {
    var = 0;
    T sign = 1;
    int cc = getchar_unlocked();
    for (; cc < '0' || '9' < cc; cc = getchar_unlocked())
      if (cc == '-')
        sign = -1;
    for (; '0' <= cc && cc <= '9'; cc = getchar_unlocked())
      var = (var << 3) + (var << 1) + cc - '0';
    var = var * sign;
  }
  inline int c() { return getchar_unlocked(); }
  inline MaiScanner &operator>>(int &var) {
    input_integer<int>(var);
    return *this;
  }
  inline MaiScanner &operator>>(long long &var) {
    input_integer<long long>(var);
    return *this;
  }
  inline MaiScanner &operator>>(string &var) {
    int cc = getchar_unlocked();
    for (; !isvisiblechar(cc); cc = getchar_unlocked())
      ;
    for (; isvisiblechar(cc); cc = getchar_unlocked())
      var.push_back(cc);
    return *this;
  }
  template <typename IT> void in(IT begin, IT end) {
    for (auto it = begin; it != end; ++it)
      *this >> *it;
  }
};
} // namespace
MaiScanner scanner;

class Flow {
public:
  typedef int cap_t;
  size_t n;
  struct Arrow {
    int from, to;
    cap_t left;
    cap_t cap;

    Arrow(int from = 0, int to = 0, cap_t w = 1)
        : from(from), to(to), left(w), cap(w) {}
    bool operator<(const Arrow &a) const {
      return (left != a.left) ? left < a.left
                              : (left < a.left) | (cap < a.cap) |
                                    (from < a.from) | (to < a.to);
    }
    bool operator==(const Arrow &a) const {
      return (from == a.from) && (to == a.to) && (left == a.left) &&
             (cap == a.cap);
    }
  };
  vector<vector<int>> vertex_to;
  vector<vector<int>> vertex_from;
  vector<Arrow> arrows;

  Flow(int n) : n(n), vertex_to(n), vertex_from(n) {}

  void connect(int from, int to, cap_t left) {
    vertex_to[from].push_back(arrows.size()); // toto
    vertex_from[to].push_back(arrows.size()); // fromfrom
    arrows.emplace_back(from, to, left);
  }
};

Flow::cap_t minconstflow(Flow &graph, const vector<Flow::cap_t> &cost,
                         int i_source, int i_sink, Flow::cap_t flow,
                         Flow::cap_t inf) {

  Flow::cap_t result = 0;
  vector<Flow::cap_t> ofs(graph.n); // potential
  vector<Flow::cap_t> dist(graph.n);

  static function<Flow::cap_t(int, Flow::cap_t)> _dfs = [&](int idx,
                                                            Flow::cap_t f) {
    if (idx == i_source)
      return f;
    for (int ei : graph.vertex_from[idx]) {
      auto &edge = graph.arrows[ei];
      if (dist[edge.to] ==
          dist[edge.from] + cost[ei] + ofs[edge.from] - ofs[edge.to]) {
        f = _dfs(edge.from, min(f, edge.left));
        edge.left -= f;
        return f;
      }
    }
    return 0;
  };

  while (flow > 0) {
    fill(dist.begin(), dist.end(), inf);
    priority_queue<pair<Flow::cap_t, int>> pq;
    pq.emplace(0, i_source);
    dist[i_source] = 0;
    while (!pq.empty()) {
      auto p = pq.top();
      pq.pop();
      Flow::cap_t d = -p.first;
      int idx = p.second;
      if (dist[idx] < d)
        continue;
      for (int ei : graph.vertex_to[idx]) {
        auto edge = graph.arrows[ei];
        if (0 < edge.left &&
            dist[idx] + cost[ei] + ofs[idx] - ofs[edge.to] < dist[edge.to]) {
          dist[edge.to] = dist[idx] + cost[ei] + ofs[idx] - ofs[edge.to];
          pq.emplace(-dist[edge.to], edge.to);
        }
      }
    }
    if (dist[i_sink] == inf)
      return -1;
    for (int i = 0; i < graph.n; ++i)
      ofs[i] += dist[i];
    Flow::cap_t z = _dfs(i_sink, flow);
    flow -= z;
    result += z * ofs[i_sink];
  }

  return result;
}

ll m, n, kei;

int main() {
  ll f;
  scanner >> n >> m >> f;

  Flow graph(n);

  vector<int> cost(m);

  repeat(i, m) {
    int u, v, c, d;
    scanner >> u >> v >> c >> d;
    graph.connect(u, v, c);
    cost[i] = d;
  }

  auto ans = minconstflow(graph, cost, 0, n - 1, f, (ll)1e8);

  cout << ans << endl;

  return 0;
}