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

#include <bits/stdc++.h>
using namespace std;
using Int = long long;
template <typename T1, typename T2> inline void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <typename T1, typename T2> inline void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

template <typename T, bool directed> struct Dinic {
  struct edge {
    Int to;
    T cap;
    Int rev;
    edge() {}
    edge(Int to, T cap, Int rev) : to(to), cap(cap), rev(rev) {}
  };

  T INF;
  vector<vector<edge>> G;
  vector<Int> level, iter;

  Dinic() {}
  Dinic(Int n, T INF) : INF(INF), G(n), level(n), iter(n) {}

  void add_edge(Int from, Int to, Int cap) {
    G[from].emplace_back(to, cap, G[to].size());
    G[to].emplace_back(from, directed ? 0 : cap, G[from].size() - 1);
  }

  void bfs(Int s) {
    fill(level.begin(), level.end(), -1);
    queue<Int> que;
    level[s] = 0;
    que.emplace(s);
    while (!que.empty()) {
      Int v = que.front();
      que.pop();
      for (Int i = 0; i < (Int)G[v].size(); i++) {
        edge &e = G[v][i];
        if (e.cap > 0 && level[e.to] < 0) {
          level[e.to] = level[v] + 1;
          que.emplace(e.to);
        }
      }
    }
  }

  T dfs(Int v, Int t, T f) {
    if (v == t)
      return f;
    for (Int &i = iter[v]; i < (Int)G[v].size(); i++) {
      edge &e = G[v][i];
      if (e.cap > 0 && level[v] < level[e.to]) {
        T d = dfs(e.to, t, min(f, e.cap));
        if (d == 0)
          continue;
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
    return 0;
  }

  T flow(Int s, Int t, T lim) {
    T fl = 0;
    while (1) {
      bfs(s);
      if (level[t] < 0 || lim == 0)
        break;
      fill(iter.begin(), iter.end(), 0);

      while (1) {
        T f = dfs(s, t, lim);
        if (f == 0)
          break;
        fl += f;
        lim -= f;
      }
    }
    return fl;
  }

  T flow(Int s, Int t) { return flow(s, t, INF); }
};

// INSERT ABOVE HERE
signed main() {
  Int n, m;
  cin >> n >> m;
  const Int INF = 1e8;
  Dinic<Int, false> G(n, INF);
  for (Int i = 0; i < m; i++) {
    Int u, v, w;
    cin >> u >> v >> w;
    G.add_edge(u, v, w);
  }

  Int res = G.flow(0, n - 1, 10010);
  Int ans = res;
  if (res - 1 <= 10000) {
    for (Int v = 0; v < n; v++) {
      for (auto &e : G.G[v]) {
        if (e.cap)
          continue;
        Int w = (e.cap + G.G[e.to][e.rev].cap) / 2;
        if (w > 1)
          continue;

        // cut edge
        G.G[e.to][e.rev].cap = 0;

        // 0 -> v -> e.to -> n-1
        Int a = G.flow(v, 0, 1);
        Int b = G.flow(n - 1, e.to, 1);
        assert(a == 1 && b == 1);

        if (G.flow(0, n - 1) == 0) {
          ans = res - 1;
          break;
        }

        // restore edge
        e.cap = 1;
        G.G[e.to][e.rev].cap = 1;

        G.flow(0, n - 1);
      }
      if (ans < res)
        break;
    }
  }
  if (ans > 10000)
    ans = -1;
  cout << ans << endl;
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using Int = long long;
template <typename T1, typename T2> inline void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <typename T1, typename T2> inline void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

template <typename T, bool directed> struct Dinic {
  struct edge {
    Int to;
    T cap;
    Int rev;
    edge() {}
    edge(Int to, T cap, Int rev) : to(to), cap(cap), rev(rev) {}
  };

  T INF;
  vector<vector<edge>> G;
  vector<Int> level, iter;

  Dinic() {}
  Dinic(Int n, T INF) : INF(INF), G(n), level(n), iter(n) {}

  void add_edge(Int from, Int to, Int cap) {
    G[from].emplace_back(to, cap, G[to].size());
    G[to].emplace_back(from, directed ? 0 : cap, G[from].size() - 1);
  }

  void bfs(Int s) {
    fill(level.begin(), level.end(), -1);
    queue<Int> que;
    level[s] = 0;
    que.emplace(s);
    while (!que.empty()) {
      Int v = que.front();
      que.pop();
      for (Int i = 0; i < (Int)G[v].size(); i++) {
        edge &e = G[v][i];
        if (e.cap > 0 && level[e.to] < 0) {
          level[e.to] = level[v] + 1;
          que.emplace(e.to);
        }
      }
    }
  }

  T dfs(Int v, Int t, T f) {
    if (v == t)
      return f;
    for (Int &i = iter[v]; i < (Int)G[v].size(); i++) {
      edge &e = G[v][i];
      if (e.cap > 0 && level[v] < level[e.to]) {
        T d = dfs(e.to, t, min(f, e.cap));
        if (d == 0)
          continue;
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
    return 0;
  }

  T flow(Int s, Int t, T lim) {
    T fl = 0;
    while (1) {
      bfs(s);
      if (level[t] < 0 || lim == 0)
        break;
      fill(iter.begin(), iter.end(), 0);

      while (1) {
        T f = dfs(s, t, lim);
        if (f == 0)
          break;
        fl += f;
        lim -= f;
      }
    }
    return fl;
  }

  T flow(Int s, Int t) { return flow(s, t, INF); }
};

// INSERT ABOVE HERE
signed main() {
  Int n, m;
  cin >> n >> m;
  const Int INF = 1e8;
  Dinic<Int, false> G(n, INF);
  for (Int i = 0; i < m; i++) {
    Int u, v, w;
    cin >> u >> v >> w;
    G.add_edge(u, v, w);
  }

  Int res = G.flow(0, n - 1, 10010);
  Int ans = res;
  for (Int v = 0; v < n; v++) {
    for (auto &e : G.G[v]) {
      if (e.cap)
        continue;
      Int w = (e.cap + G.G[e.to][e.rev].cap) / 2;
      if (w > 1)
        continue;

      // cut edge
      G.G[e.to][e.rev].cap = 0;

      // 0 -> v -> e.to -> n-1
      Int a = G.flow(v, 0, 1);
      Int b = G.flow(n - 1, e.to, 1);
      assert(a == 1 && b == 1);

      if (G.flow(0, n - 1) == 0)
        ans = res - 1;

      // restore edge
      e.cap = 1;
      G.G[e.to][e.rev].cap = 1;

      G.flow(0, n - 1);
    }
  }

  if (ans > 10000)
    ans = -1;
  cout << ans << endl;
  return 0;
}