Problem p01706 (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;
}

struct Dinic {
  const int INF = 1 << 28;

  struct edge {
    int to, cap, rev;
    edge() {}
    edge(int to, int cap, int rev) : to(to), cap(cap), rev(rev) {}
  };

  int n;
  vector<vector<edge>> G;
  vector<map<int, int>> M;
  vector<int> level, iter;

  Dinic() {}
  Dinic(int sz) : n(sz), G(n), M(n), level(n), iter(n) {}

  void add_edge(int from, int to, int cap) {
    M[from][to] = G[from].size();
    M[to][from] = G[to].size();
    G[from].push_back(edge(to, cap, G[to].size()));
    // undirected
    // G[to].push_back(edge(from,cap,G[from].size()-1));
    // directed
    G[to].push_back(edge(from, 0, G[from].size() - 1));
  }

  void bfs(int s) {
    fill(level.begin(), level.end(), -1);
    queue<int> que;
    level[s] = 0;
    que.push(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.push(e.to);
        }
      }
    }
  }

  int dfs(int v, int t, int 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]) {
        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 flow(int s, int t, int lim) {
    int fl = 0;
    for (;;) {
      bfs(s);
      if (level[t] < 0 || lim == 0)
        return fl;
      fill(iter.begin(), iter.end(), 0);
      int f;
      while ((f = dfs(s, t, lim)) > 0) {
        fl += f;
        lim -= f;
      }
    }
  }

  int flow(int s, int t) { return flow(s, t, INF); }

  // cap==1 only
  bool back_edge(int s, int t, int from, int to) {
    for (int i = 0; i < (int)G[from].size(); i++) {
      edge &e = G[from][i];
      if (e.to == to) {
        if (e.cap == 0 && flow(from, to, 1) == 0) {
          flow(from, s, 1);
          flow(t, to, 1);
          return 1;
        }
      }
    }
    return 0;
  }
};

// INSERT ABOVE HERE
signed main() {
  int n, m, s, t;
  while (cin >> n >> m >> s >> t, n) {
    vector<int> a(m), b(m);
    for (int i = 0; i < m; i++)
      cin >> a[i] >> b[i];
    s--;
    t--;
    for (int i = 0; i < m; i++)
      a[i]--, b[i]--;

    Dinic flow(n);
    for (int i = 0; i < m; i++)
      flow.add_edge(a[i], b[i], 1);

    int cur = flow.flow(s, t), res = cur, cnt = 0;
    auto &G = flow.G;
    auto &M = flow.M;

    auto bfs = [&](int v, vector<int> &dp, int k) {
      dp.assign(n, 0);
      queue<int> q;
      q.emplace(v);
      dp[v] = 1;
      while (!q.empty()) {
        v = q.front();
        q.pop();
        for (auto &e : G[v]) {
          if (e.cap != k || dp[e.to])
            continue;
          dp[e.to] = 1;
          q.emplace(e.to);
        }
      }
    };

    vector<int> dp1, dp2;
    bfs(s, dp1, 1);
    bfs(t, dp2, 0);

    for (int i = 0; i < m; i++) {
      int k = M[a[i]][b[i]];
      // cout<<G[a[i]][k].cap<<" "<<dp1[b[i]]<<" "<<dp2[a[i]]<<endl;
      if (G[a[i]][k].cap == 0)
        continue;
      if (dp1[b[i]] && dp2[a[i]])
        res = cur + 1, cnt++;
    }

    cout << res << " " << cnt << 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;
}

struct Dinic {
  const int INF = 1 << 28;

  struct edge {
    int to, cap, rev;
    edge() {}
    edge(int to, int cap, int rev) : to(to), cap(cap), rev(rev) {}
  };

  int n;
  vector<vector<edge>> G;
  vector<map<int, int>> M;
  vector<int> level, iter;

  Dinic() {}
  Dinic(int sz) : n(sz), G(n), M(n), level(n), iter(n) {}

  void add_edge(int from, int to, int cap) {
    M[from][to] = G[from].size();
    M[to][from] = G[to].size();
    G[from].push_back(edge(to, cap, G[to].size()));
    // undirected
    // G[to].push_back(edge(from,cap,G[from].size()-1));
    // directed
    G[to].push_back(edge(from, 0, G[from].size() - 1));
  }

  void bfs(int s) {
    fill(level.begin(), level.end(), -1);
    queue<int> que;
    level[s] = 0;
    que.push(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.push(e.to);
        }
      }
    }
  }

  int dfs(int v, int t, int 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]) {
        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 flow(int s, int t, int lim) {
    int fl = 0;
    for (;;) {
      bfs(s);
      if (level[t] < 0 || lim == 0)
        return fl;
      fill(iter.begin(), iter.end(), 0);
      int f;
      while ((f = dfs(s, t, lim)) > 0) {
        fl += f;
        lim -= f;
      }
    }
  }

  int flow(int s, int t) { return flow(s, t, INF); }

  // cap==1 only
  bool back_edge(int s, int t, int from, int to) {
    for (int i = 0; i < (int)G[from].size(); i++) {
      edge &e = G[from][i];
      if (e.to == to) {
        if (e.cap == 0 && flow(from, to, 1) == 0) {
          flow(from, s, 1);
          flow(t, to, 1);
          return 1;
        }
      }
    }
    return 0;
  }
};

// INSERT ABOVE HERE
signed main() {
  int n, m, s, t;
  while (cin >> n >> m >> s >> t, n) {
    vector<int> a(m), b(m);
    for (int i = 0; i < m; i++)
      cin >> a[i] >> b[i];
    s--;
    t--;
    for (int i = 0; i < m; i++)
      a[i]--, b[i]--;

    auto calc = [&](int k) -> int {
      Dinic G(n);
      for (int i = 0; i < m; i++) {
        if (i == k)
          G.add_edge(b[i], a[i], 1);
        else
          G.add_edge(a[i], b[i], 1);
      }
      return G.flow(s, t);
    };

    int cur = calc(-1), res = cur, cnt = 0;
    for (int i = 0; i < m; i++) {
      int tmp = calc(i);
      if (tmp > cur) {
        res = tmp;
        cnt++;
      }
    }
    cout << res << " " << cnt << endl;
  }
  return 0;
}