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

#include <bits/stdc++.h>
using namespace std;
#define REP(i, n) for (int i = 0; i < int(n); ++i)
#define MAX_V 10000
int V;

using Weight = int;

const Weight INF = 1000000000;
// const Weight eps = 1e-8;

struct Edge {
  int src, dest;
  int cap, rev;
  bool isReal;
};
using Edges = vector<Edge>;
using Graph = vector<Edges>;

int d[MAX_V];
int iter[MAX_V];

void add_edge(Graph &g, int src, int dest, int cap) {
  g[src].push_back((Edge){src, dest, cap, (int)g[dest].size(), true});
  g[dest].push_back((Edge){dest, src, 0, (int)g[src].size() - 1, false});
}

void bfs(Graph &g, int s) {
  memset(d, -1, sizeof(d));
  queue<int> que;
  d[s] = 0;
  que.push(s);
  while (!que.empty()) {
    int v = que.front();
    que.pop();
    REP(i, g[v].size()) {
      Edge &e = g[v][i];
      if (e.cap > 0 && d[e.dest] < 0) {
        d[e.dest] = d[v] + 1;
        que.push(e.dest);
      }
    }
  }
}

int dfs(Graph &g, 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 && d[v] < d[e.dest]) {
      int d = dfs(g, e.dest, t, min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        g[e.dest][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

int max_flow(Graph &g, int s, int t) {
  int flow = 0;
  for (;;) {
    bfs(g, s);
    if (d[t] < 0)
      return flow;
    memset(iter, 0, sizeof(iter));
    int f;
    while ((f = dfs(g, s, t, INF)) > 0)
      flow += f;
  }
}
int main() {
  int n, m, s, t;
  while (cin >> n >> m >> s >> t, n) {
    s--, t--;
    vector<int> a(m), b(m);
    for (int i = 0; i < m; i++) {
      cin >> a[i] >> b[i];
      a[i]--, b[i]--;
    }
    Graph g(n);
    for (int i = 0; i < m; i++) {
      add_edge(g, a[i], b[i], 1);
    }

    int f = max_flow(g, s, t);

    vector<int> ca, cb;

    function<void(int, Graph &, vector<int> &)> mydfs = [&](int v, Graph &graph,
                                                            vector<int> &used) {
      if (used[v])
        return;
      used[v] = true;
      for (int i = 0; i < graph[v].size(); i++)
        if (graph[v][i].cap > 0)
          mydfs(graph[v][i].dest, graph, used);
      return;
    };
    vector<int> sside(n);
    mydfs(s, g, sside);

    for (int i = 0; i < n; i++) {
      for (int j = 0; j < g[i].size(); j++) {
        if (!g[i][j].isReal)
          continue;
        if (!sside[i] && sside[g[i][j].dest]) {
          ca.push_back(g[i][j].dest);
          cb.push_back(i);
        }
      }
    }
    int res = 0;
    for (int i = 0; i < ca.size(); i++) {
      int aa = ca[i], bb = cb[i];
      Graph newg = g;
      add_edge(newg, aa, bb, 1);
      int f2 = max_flow(newg, s, t);
      if (f2 > 0)
        res++;
    }
    if (res == 0) {
      cout << f << " " << 0 << endl;
    } else {
      cout << f + 1 << " " << res << endl;
    }
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define REP(i, n) for (int i = 0; i < int(n); ++i)
#define MAX_V 10000
int V;

using Weight = int;

const Weight INF = 1000000000;
// const Weight eps = 1e-8;

struct Edge {
  int src, dest;
  int cap, rev;
  bool isReal;
};
using Edges = vector<Edge>;
using Graph = vector<Edges>;

int d[MAX_V];
int iter[MAX_V];

void add_edge(Graph &g, int src, int dest, int cap) {
  g[src].push_back((Edge){src, dest, cap, (int)g[dest].size(), true});
  g[dest].push_back((Edge){dest, src, 0, (int)g[src].size() - 1, false});
}

void bfs(Graph &g, int s) {
  memset(d, -1, sizeof(d));
  queue<int> que;
  d[s] = 0;
  que.push(s);
  while (!que.empty()) {
    int v = que.front();
    que.pop();
    REP(i, g[v].size()) {
      Edge &e = g[v][i];
      if (e.cap > 0 && d[e.dest] < 0) {
        d[e.dest] = d[v] + 1;
        que.push(e.dest);
      }
    }
  }
}

int dfs(Graph &g, 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 && d[v] < d[e.dest]) {
      int d = dfs(g, e.dest, t, min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        g[e.dest][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

int max_flow(Graph &g, int s, int t) {
  int flow = 0;
  for (;;) {
    bfs(g, s);
    if (d[t] < 0)
      return flow;
    memset(iter, 0, sizeof(iter));
    int f;
    while ((f = dfs(g, s, t, INF)) > 0)
      flow += f;
  }
}
int main() {
  int n, m, s, t;
  while (cin >> n >> m >> s >> t) {
    s--, t--;
    vector<int> a(m), b(m);
    for (int i = 0; i < m; i++) {
      cin >> a[i] >> b[i];
      a[i]--, b[i]--;
    }
    Graph g(n);
    for (int i = 0; i < m; i++) {
      add_edge(g, a[i], b[i], 1);
    }

    int f = max_flow(g, s, t);

    vector<int> ca, cb;
    Graph gr(n);
    Graph rgr(n);
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < g[i].size(); j++) {
        if (!g[i][j].isReal || g[i][j].cap == 0)
          continue;
        gr[i].push_back(Edge{i, g[i][j].dest, 0, 0});
        rgr[g[i][j].dest].push_back(Edge{g[i][j].dest, i, 0, 0});
      }
    }

    function<void(int, Graph &, vector<int> &)> mydfs = [&](int v, Graph &graph,
                                                            vector<int> &used) {
      if (used[v])
        return;
      used[v] = true;
      for (int i = 0; i < graph[v].size(); i++)
        mydfs(graph[v][i].dest, graph, used);
      return;
    };
    /*
    vector<int> used(n,false),rused(n,false);
    mydfs(s,gr,used);
    mydfs(t,rgr,rused);
    for(int i=0;i<n;i++) cerr<<used[i];
    cerr<<endl;

    for(int i=0;i<n;i++) cerr<<rused[i];
    cerr<<endl;

   for(int i=0;i<gr.size();i++){
      for(int j=0;j<gr[i].size();j++){
        int to=gr[i][j].dest;
        if(!used[i] && used[to] && rused[i] && !rused[to]){
          ca.push_back(i);
          cb.push_back(to);
        }
      }
    }
    */
    int res = 0;
    for (int i = 0; i < gr.size(); i++)
      for (int j = 0; j < gr[i].size(); j++) {
        int aa = i, bb = gr[i][j].dest;
        Graph newg = g;
        add_edge(newg, bb, aa, 1);
        int f2 = max_flow(newg, s, t);
        if (f2 > 0)
          res++;
      }
    if (res == 0) {
      cout << f << " " << 0 << endl;
    } else {
      cout << f + 1 << " " << res << endl;
    }
  }

  return 0;
}