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

#include <bits/stdc++.h>
using namespace std;
#define MAX 105
#define INF (1e8)
int K, N, M;
int T;

bool g[MAX][MAX];
int G[MAX][MAX];
int C[MAX];
int tmp[MAX][MAX];

bool visited[MAX];
bool used[MAX];

void copyA() {
  for (int i = 0; i < MAX; i++)
    for (int j = 0; j < MAX; j++)
      tmp[i][j] = G[i][j];
}
void copyB() {
  for (int i = 0; i < MAX; i++)
    for (int j = 0; j < MAX; j++)
      G[i][j] = tmp[i][j];
}

int dfs(int pos, int ti, int f) {
  if (pos == ti)
    return f;
  visited[pos] = true;
  for (int tt = -1; tt < T; tt++) {
    int to = tt;
    if (to == -1)
      to = T;

    if (visited[to])
      continue;
    if (G[pos][to] == 0)
      continue;

    int k = dfs(to, ti, min(f, G[pos][to]));
    if (k > 0) {
      G[pos][to] -= k;
      G[to][pos] += k;
      return k;
    }
  }
  return 0;
}

int maxFlow(int si, int ti) {
  if (si == ti)
    return INF;
  int res = 0;
  while (1) {
    memset(visited, false, sizeof(visited));
    int f = dfs(si, ti, INF);
    if (f == 0)
      break;
    res += f;
  }
  return res;
}
int calcC(int id) {
  if (C[id] != -1)
    return C[id];
  copyA();
  if (used[id]) {
    C[id] = maxFlow(T, id);
  } else {
    C[id] = maxFlow(id, 0);
  }
  copyB();
  return C[id];
}

int main() {
  memset(C, -1, sizeof(C));

  bool isOverfuro = false;
  cin >> K >> N >> M;
  T = N + K + 1;
  for (int i = 0; i < M; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    if (a == 0 && 1 <= b && b <= K) {
      isOverfuro = true;
    }
    if (b == 0 && 1 <= a && a <= K) {
      isOverfuro = true;
    }
    G[a][b] += c;
    G[b][a] += c;
    g[a][b] = true;
    g[b][a] = true;
  }

  for (int i = 1; i <= K; i++) {
    G[T][i] = INF;
  }

  if (isOverfuro) {
    cout << "overfuro" << endl;
    return 0;
  }

  int F = maxFlow(T, 0);
  assert(F > 0);

  memset(visited, false, sizeof(visited));
  dfs(T, 0, INF);

  for (int i = 0; i <= T; i++) {
    used[i] = visited[i];
  }

  C[0] = INF;

  int ans = 0;
  for (int i = 0; i < T; i++) {
    for (int j = 0; j < T; j++) {
      if (i == j)
        continue;
      if (G[i][j] == 0 && g[i][j] == true && used[i] == true &&
          used[j] == false) {
        calcC(i);
        calcC(j);
        ans = max(ans, min(C[i], C[j]));
      }
    }
  }
  cout << F + ans << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define MAX 105
#define INF (1e8)
int K, N, M;
int T;

bool g[MAX][MAX];
int G[MAX][MAX];
int C[MAX];
int tmp[MAX][MAX];

bool visited[MAX];
bool used[MAX];

void copyA() {
  for (int i = 0; i < MAX; i++)
    for (int j = 0; j < MAX; j++)
      tmp[i][j] = G[i][j];
}
void copyB() {
  for (int i = 0; i < MAX; i++)
    for (int j = 0; j < MAX; j++)
      G[i][j] = tmp[i][j];
}

int dfs(int pos, int ti, int f) {
  if (pos == ti)
    return f;
  visited[pos] = true;
  for (int to = 0; to <= T; to++) {
    if (visited[to])
      continue;
    if (G[pos][to] == 0)
      continue;

    int k = dfs(to, ti, min(f, G[pos][to]));
    if (k > 0) {
      G[pos][to] -= k;
      G[to][pos] += k;
      return k;
    }
  }
  return 0;
}

int maxFlow(int si, int ti) {
  int res = 0;
  while (1) {
    memset(visited, false, sizeof(visited));
    int f = dfs(si, ti, INF);
    if (f == 0)
      break;
    res += f;
  }
  return res;
}

int main() {
  bool isOverfuro = false;
  cin >> K >> N >> M;
  T = N + K + 1;
  for (int i = 0; i < M; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    if (a == 0 && 1 <= b && b <= K) {
      isOverfuro = true;
    }
    if (b == 0 && 1 <= a && a <= K) {
      isOverfuro = true;
    }
    G[a][b] += c;
    G[b][a] += c;
    g[a][b] = true;
    g[b][a] = true;
  }

  for (int i = 1; i <= K; i++) {
    G[T][i] = INF;
  }

  if (isOverfuro) {
    cout << "overfuro" << endl;
    return 0;
  }

  int F = maxFlow(T, 0);
  assert(F > 0);

  memset(visited, false, sizeof(visited));
  dfs(T, 0, INF);

  for (int i = 0; i <= T; i++) {
    used[i] = visited[i];
  }

  for (int i = 1; i < T; i++) {
    copyA();
    if (used[i] == true) {
      memset(visited, false, sizeof(visited));
      C[i] = maxFlow(T, i);
    } else {
      memset(visited, false, sizeof(visited));
      C[i] = maxFlow(i, 0);
    }
    copyB();
  }
  C[0] = INF;

  int ans = 0;
  for (int i = 0; i < T; i++) {
    for (int j = 0; j < T; j++) {
      if (i == j)
        continue;
      if (G[i][j] == 0 && g[i][j] == true && used[i] == true &&
          used[j] == false) {
        ans = max(ans, min(C[i], C[j]));
      }
    }
  }
  cout << F + ans << endl;
  return 0;
}