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

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int INF = 1000000000;
void rec(vector<vector<vector<bool>>> &D, vector<vector<int>> &G, vector<int> d,
         int v, int n) {
  int m = 0;
  for (int i = 0; i < 3; ++i)
    m = max(m, G[v][i]);
  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < n; ++j) {
      if (D[i][v][j]) {
        if (G[j][i] <= m + 1)
          continue;
        G[j][i] = m + 1;
        bool f = true;
        for (int k = 0; k < 3; ++k) {
          if (G[j][k] == INF) {
            f = false;
            break;
          }
        }
        if (f) {
          rec(D, G, d, j, n);
        }
      }
    }
  }
}

vector<vector<bool>> matrix_product(vector<vector<bool>> &a,
                                    vector<vector<bool>> &b) {
  int n = a.size(), m = b[0].size(), l = a[0].size();
  vector<vector<bool>> ret(a.size(), vector<bool>(b[0].size(), false));
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      for (int k = 0; k < l; ++k) {
        ret[i][j] = (a[i][k] & b[k][j]) | ret[i][j];
      }
    }
  }
  return ret;
}

vector<vector<bool>> matrix_pow(vector<vector<bool>> &G, int n) {
  vector<vector<bool>> ret = G;
  for (int i = 0; i < n - 1; ++i) {
    ret = matrix_product(ret, G);
  }
  return ret;
}

int main() {
  int n, m, a, b, c;
  cin >> n >> m >> a >> b >> c;
  int u, v;
  vector<vector<bool>> G(n, vector<bool>(n, false));
  for (int i = 0; i < m; ++i) {
    cin >> u >> v;
    --u;
    --v;
    G[v][u] = 1;
  }

  vector<vector<vector<bool>>> D(3);
  vector<int> d = {a, b, c};
  for (int i = 0; i < 3; ++i)
    D[i] = matrix_pow(G, d[i]);
  /*
  for(int i = 0; i < 3; ++i){
    cout << "--------------------" << d[i] << "----------------------------" <<
  endl; for(int j = 0; j < n; ++j){ for(int k = 0; k < n; ++k){ cout <<
  D[i][j][k] << " " ; }cout << endl;
    }
  }
  */
  vector<vector<int>> G_(n, vector<int>(n, INF));
  for (int i = 0; i < 3; ++i)
    G_[n - 1][i] = 0;

  rec(D, G_, d, n - 1, n);
  if (G_[0][0] == INF || G_[0][1] == INF || G_[0][2] == INF)
    cout << "IMPOSSIBLE" << endl;
  else
    cout << max({G_[0][0], G_[0][1], G_[0][2]}) << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <vector>
using namespace std;
int INF = 1000000000;
void rec(vector<vector<vector<bool>>> &D, vector<vector<int>> &G, vector<int> d,
         int v, int n) {
  int m = 0;
  for (int i = 0; i < 3; ++i)
    m = max(m, G[v][i]);
  for (int i = 0; i < 3; ++i)
    G[v][i] = m;
  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < n; ++j) {
      if (D[i][v][j]) {
        if (G[j][i] <= G[v][i] + 1)
          continue;
        G[j][i] = G[v][i] + 1;
        bool f = true;
        for (int k = 0; k < 3; ++k) {
          if (G[j][k] == INF) {
            f = false;
            break;
          }
        }
        if (f) {
          rec(D, G, d, j, n);
        }
      }
    }
  }
}

vector<vector<bool>> matrix_product(vector<vector<bool>> &a,
                                    vector<vector<bool>> &b) {
  int n = a.size(), m = b[0].size(), l = a[0].size();
  vector<vector<bool>> ret(a.size(), vector<bool>(b[0].size(), false));
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      for (int k = 0; k < l; ++k) {
        ret[i][j] = (a[i][k] & b[k][j]) | ret[i][j];
      }
    }
  }
  return ret;
}

vector<vector<bool>> matrix_pow(vector<vector<bool>> &G, int n) {
  vector<vector<bool>> ret = G;
  for (int i = 0; i < n - 1; ++i) {
    ret = matrix_product(ret, G);
  }
  return ret;
}

int main() {
  int n, m, a, b, c;
  cin >> n >> m >> a >> b >> c;
  int u, v;
  vector<vector<bool>> G(n, vector<bool>(n, false));
  for (int i = 0; i < m; ++i) {
    cin >> u >> v;
    --u;
    --v;
    G[v][u] = 1;
  }

  vector<vector<vector<bool>>> D(3);
  vector<int> d = {a, b, c};
  for (int i = 0; i < 3; ++i)
    D[i] = matrix_pow(G, d[i]);
  /*
  for(int i = 0; i < 3; ++i){
    cout << "--------------------" << d[i] << "----------------------------" <<
  endl; for(int j = 0; j < n; ++j){ for(int k = 0; k < n; ++k){ cout <<
  D[i][j][k] << " " ; }cout << endl;
    }
  }
  */
  vector<vector<int>> G_(n, vector<int>(n, INF));
  for (int i = 0; i < 3; ++i)
    G_[n - 1][i] = 0;

  rec(D, G_, d, n - 1, n);
  if (G_[0][0] == INF || G_[0][1] == INF || G_[0][2] == INF)
    cout << "IMPOSSIBLE" << endl;
  else
    cout << G[0][0] << endl;
  return 0;
}