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

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

struct edge {
  int to, cap, org, rev;
};

vector<edge> G[1234];
bool used[1234];

void add_edge(int from, int to) {
  G[from].push_back({to, 1, 1, (int)G[to].size()});
  G[to].push_back({from, 0, 0, (int)G[from].size() - 1});
}

int dfs(int v, int t, int f) {
  if (v == t)
    return f;
  used[v] = true;
  for (int i = 0; i < G[v].size(); i++) {
    edge &e = G[v][i];
    if (!used[e.to] && e.cap > 0) {
      int d = dfs(e.to, t, min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

int max_flow(int s, int t) {
  int flow = 0;
  for (;;) {
    fill(begin(used), end(used), false);
    int f = dfs(s, t, 1e9);
    if (f == 0)
      return flow;
    flow += f;
  }
}

bool u1[1234], u2[1234];

void dfsr(int v) {
  if (u1[v]++)
    return;
  for (auto e : G[v]) {
    if (e.cap) {
      dfsr(e.to);
    }
  }
}

void rdfsr(int v) {
  if (u2[v]++)
    return;
  for (auto e : G[v]) {
    if (!e.cap) {
      rdfsr(e.to);
    }
  }
}

int main() {
  for (int N, M, S, T; cin >> N >> M >> S >> T, N | M | S | T;) {
    for (auto &e : G) {
      e.clear();
    }
    fill(begin(u1), end(u1), false);
    fill(begin(u2), end(u2), false);
    for (int i = 0; i < M; i++) {
      int a, b;
      cin >> a >> b;
      add_edge(a, b);
    }
    int f = max_flow(S, T);
    dfsr(S);
    rdfsr(T);
    int c = 0;
    for (int i = 1; i <= N; i++) {
      for (auto e : G[i]) {
        if (e.cap && e.org && u1[e.to] && u2[i]) {
          c++;
        }
      }
    }
    cout << f + !!c << ' ' << c << endl;
  }
}


Error: TLE

Fixed submission:

#include <iostream>
#include <queue>
#include <tuple>
#include <vector>

using namespace std;

struct edge {
  int to, cap, rev;
};

vector<edge> G[1234];
int level[1234];
int iter[1234];

vector<tuple<int, int, int, int>> edges;

void add_edge(int from, int to, int cap = 1) {
  edges.emplace_back(from, (int)G[from].size(), to, (int)G[to].size());
  G[from].push_back({to, cap, (int)G[to].size()});
  G[to].push_back({from, 0, (int)G[from].size() - 1});
}

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

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

int max_flow(int s, int t, int mf = 1e9) {
  int flow = 0;
  for (;;) {
    bfs(s);
    if (level[t] < 0)
      return flow;
    fill(begin(iter), end(iter), 0);
    int f;
    while ((f = dfs(s, t, mf)) > 0) {
      flow += f;
      if (flow == mf)
        return flow;
    }
  }
}

int main() {
  for (int N, M, S, T; cin >> N >> M >> S >> T, N | M | S | T;) {
    edges.clear();
    for (auto &e : G) {
      e.clear();
    }
    for (int i = 0; i < M; i++) {
      int a, b;
      cin >> a >> b;
      add_edge(a, b);
    }
    int df = max_flow(S, T);
    int nr = 0;
    for (int i = 0; i < M; i++) {
      int f, fx, t, tx;
      tie(f, fx, t, tx) = edges[i];
      bool rev = false;
      if (G[f][fx].cap == 0) {
        rev = true;
        max_flow(f, S, 1);
        max_flow(T, t, 1);
      }
      G[f][fx].cap = 0;
      G[t][tx].cap = 1;
      if (max_flow(S, T) > rev) {
        nr++;
      }
      if (G[t][tx].cap == 0) {
        max_flow(T, f, 1);
        max_flow(t, S, 1);
      }
      G[f][fx].cap = 1;
      G[t][tx].cap = 0;
      max_flow(S, T);
    }
    cout << df + !!nr << ' ' << nr << endl;
  }
}