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

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

#define INF (1 << 28)

class Edge {
public:
  int src, dst, cst;
  Edge() {}
  Edge(int s, int d, int c) : src(s), dst(d), cst(c) {}
};

typedef vector<vector<Edge>> Graph;

int capa[502][502];

int dfs(int p, int T, int mf, Graph &graph, vector<int> &level,
        vector<bool> &finished) {
  if (p == T)
    return mf;
  if (finished[p])
    return 0;

  finished[p] = true;

  for (int i = 0; i < graph[p].size(); i++) {
    Edge &e = graph[p][i];
    int next = e.dst, fw = capa[p][next];
    if (level[p] >= level[next])
      continue;
    if (fw <= 0)
      continue;

    int f = dfs(next, T, min(mf, fw), graph, level, finished);
    if (f > 0) {
      finished[p] = false;
      capa[p][next] -= f;
      capa[next][p] += f;
      return f;
    }
  }

  return 0;
}

// 流量を制限するdinic
int dinic(int S, int T, int L, Graph &graph) {
  bool end = false;
  int total = 0;
  while (!end && total < L) {
    end = true;
    vector<int> level(graph.size(), -1);
    level[S] = 0;

    queue<int> q;
    q.push(S);
    while (!q.empty()) {
      int n = q.front();
      q.pop();
      for (int i = 0; i < graph[n].size(); i++) {
        Edge &e = graph[n][i];

        int next = e.dst;
        if (level[next] != -1)
          continue;
        if (capa[n][next] <= 0)
          continue;
        level[next] = level[n] + 1;
        q.push(next);
      }
    }

    if (level[T] == -1)
      break;

    vector<bool> finished(graph.size());
    while (1) {
      int fw = dfs(S, T, L, graph, level, finished);
      if (fw <= 0)
        break;

      total += fw;
      end = false;
      if (total >= L)
        break;
    }
  }

  return total;
}

void add_edge(int s, int t, int v, Graph &g) {
  g[s].push_back(Edge(s, t, v));
  g[t].push_back(Edge(t, s, v));

  capa[s][t] += v;
  capa[t][s] += v;
}

void add_pass(int s, int t, Graph &g) {
  g[s].push_back(Edge(s, t, 0));
  g[t].push_back(Edge(t, s, 0));
}

void reduce_cap(int s, int t, int v, Graph &g) {
  capa[s][t] -= v;
  capa[t][s] -= v;
}

void add_cap(int s, int t, int v, Graph &g) {
  capa[s][t] += v;
  capa[t][s] += v;
}

void solve(int N, Graph &g, vector<Edge> &queries) {
  int f = dinic(0, N - 1, INF, g);
  for (int i = 0; i < queries.size(); i++) {
    Edge &e = queries[i];

    if (e.cst == 1) {
      add_cap(e.src, e.dst, 1, g);
      f += dinic(0, N - 1, 1, g);
    } else {
      if (capa[e.src][e.dst] == 1) {
        reduce_cap(e.src, e.dst, 1, g);
      }

      else if (capa[e.src][e.dst] == 2) {
        if (dinic(e.dst, e.src, 1, g) != 1) {
          f--;
          dinic(N - 1, 0, 1, g);
          dinic(e.dst, e.src, 1, g);
        }

        dinic(e.src, e.dst, 1, g);
        reduce_cap(e.src, e.dst, 1, g);
        f += dinic(0, N - 1, 1, g);

      } else {
        if (dinic(e.src, e.dst, 1, g) != 1) {
          f--;
          dinic(N - 1, 0, 1, g);
          dinic(e.src, e.dst, 1, g);
        }

        dinic(e.dst, e.src, 1, g);
        reduce_cap(e.src, e.dst, 1, g);
        f += dinic(0, N - 1, 1, g);
      }
    }

    cout << f << endl;
  }
}

int main() {
  int N, E, Q;
  cin >> N >> E >> Q;

  memset(capa, 0, sizeof(capa));

  Graph g(N);
  for (int i = 0; i < E; i++) {
    int s, t;
    cin >> s >> t;
    s--;
    t--;
    add_edge(s, t, 1, g);
  }

  vector<Edge> queries(Q);

  for (int i = 0; i < Q; i++) {
    int m, s, t;
    cin >> m >> s >> t;
    s--;
    t--;
    queries[i] = Edge(s, t, m);
    if (capa[s][t] == 0)
      add_pass(s, t, g);
  }

  solve(N, g, queries);
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

#define INF (1 << 28)

class Edge {
public:
  int src, dst, cst;
  Edge() {}
  Edge(int s, int d, int c) : src(s), dst(d), cst(c) {}
};

typedef vector<vector<Edge>> Graph;

int flow[502][502], capa[502][502];

int dfs(int p, int T, int mf, Graph &graph, vector<int> &level,
        vector<bool> &finished) {
  if (p == T)
    return mf;
  if (finished[p])
    return 0;

  finished[p] = true;

  for (int i = 0; i < graph[p].size(); i++) {
    Edge &e = graph[p][i];
    int next = e.dst, fw = capa[p][next] - flow[p][next];
    if (level[p] >= level[next])
      continue;
    if (fw <= 0)
      continue;

    int f = dfs(next, T, min(mf, fw), graph, level, finished);
    if (f > 0) {
      finished[p] = false;
      flow[p][next] += f;
      flow[next][p] -= f;
      return f;
    }
  }

  return 0;
}

// 流量を制限するdinic
int dinic(int S, int T, int L, Graph &graph) {
  bool end = false;
  int total = 0;
  while (!end && total < L) {
    end = true;
    vector<int> level(graph.size(), -1);
    level[S] = 0;

    queue<int> q;
    q.push(S);
    while (!q.empty()) {
      int n = q.front();
      q.pop();
      for (int i = 0; i < graph[n].size(); i++) {
        Edge &e = graph[n][i];

        int next = e.dst;
        if (level[next] != -1)
          continue;
        if (capa[n][next] - flow[n][next] <= 0)
          continue;
        level[next] = level[n] + 1;
        q.push(next);
      }
    }

    if (level[T] == -1)
      break;

    vector<bool> finished(graph.size());
    while (1) {
      int fw = dfs(S, T, L, graph, level, finished);
      if (fw <= 0)
        break;

      total += fw;
      end = false;
      if (total >= L)
        break;
    }
  }

  return total;
}

void add_edge(int s, int t, int v, Graph &g) {
  g[s].push_back(Edge(s, t, v));
  g[t].push_back(Edge(t, s, v));

  capa[s][t] += v;
  capa[t][s] += v;
}

void add_pass(int s, int t, Graph &g) {
  g[s].push_back(Edge(s, t, 0));
  g[t].push_back(Edge(t, s, 0));
}

void reduce_cap(int s, int t, int v, Graph &g) {
  capa[s][t] -= v;
  capa[t][s] -= v;
}

void add_cap(int s, int t, int v, Graph &g) {
  capa[s][t] += v;
  capa[t][s] += v;
}

void solve(int N, Graph &g, vector<Edge> &queries) {
  int f = dinic(0, N - 1, INF, g);
  for (int i = 0; i < queries.size(); i++) {
    Edge &e = queries[i];

    if (e.cst == 1) {
      add_cap(e.src, e.dst, 1, g);
      f += dinic(0, N - 1, 1, g);
    } else {
      if (flow[e.src][e.dst] == 0) {
        reduce_cap(e.src, e.dst, 1, g);
      } else {
        while (flow[e.src][e.dst] != 0) {
          f -= dinic(N - 1, 0, 1, g);
        }

        reduce_cap(e.src, e.dst, 1, g);
        f += dinic(0, N - 1, INF, g);
      }
    }

    cout << f << endl;
  }
}

int main() {
  int N, E, Q;
  cin >> N >> E >> Q;

  memset(flow, 0, sizeof(flow));
  memset(capa, 0, sizeof(capa));

  Graph g(N);
  for (int i = 0; i < E; i++) {
    int s, t;
    cin >> s >> t;
    s--;
    t--;
    add_edge(s, t, 1, g);
  }

  vector<Edge> queries(Q);

  for (int i = 0; i < Q; i++) {
    int m, s, t;
    cin >> m >> s >> t;
    s--;
    t--;
    queries[i] = Edge(s, t, m);
    if (capa[s][t] == 0)
      add_pass(s, t, g);
  }

  solve(N, g, queries);
}