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

#include <bits/stdc++.h>
using namespace std;
const int maxn = 53;
int n, m, A, B, C;
bool e[maxn][maxn];
void init() {
  scanf("%d%d%d%d%d", &n, &m, &A, &B, &C);
  memset(e, 0, sizeof(e));
  for (int i = 1, a, b; i <= m; ++i) {
    scanf("%d%d", &a, &b);
    e[a][b] = 1;
  }
}
bool Can[maxn][maxn];
struct Tmx {
  bool a[maxn][maxn];
  void clear() { memset(a, 0, sizeof(a)); }
};
Tmx operator*(Tmx a, Tmx b) {
  Tmx c;
  c.clear();
  for (int k = 1; k <= n; ++k)
    for (int i = 1; i <= n; ++i)
      for (int j = 1; j <= n; ++j)
        c.a[i][j] |= a.a[i][k] & b.a[k][j];
  return c;
}
void work() {
  Tmx a;
  memcpy(a.a, e, sizeof(e));

  Tmx tmp1 = a;
  for (int i = 1; i < A; ++i)
    tmp1 = tmp1 * a;

  Tmx tmp2 = a;
  for (int i = 1; i < B; ++i)
    tmp2 = tmp2 * a;

  Tmx tmp3 = a;
  for (int i = 1; i < C; ++i)
    tmp3 = tmp3 * a;

  static int ans[maxn];
  memset(ans, 63, sizeof(ans));
  ans[n] = 0;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      int res1 = -1, res2 = ans[0];
      for (int k = 1; k <= n; ++k)
        if (tmp1.a[j][k])
          res2 = min(res2, ans[k] + 1);
      res1 = res2;
      res2 = ans[0];
      for (int k = 1; k <= n; ++k)
        if (tmp2.a[j][k])
          res2 = min(res2, ans[k] + 1);
      res1 = max(res1, res2);
      res2 = ans[0];
      for (int k = 1; k <= n; ++k)
        if (tmp3.a[j][k])
          res2 = min(res2, ans[k] + 1);
      res1 = max(res1, res2);
      if (res1 < ans[j])
        ans[j] = res1;
    }
  }
  if (ans[1] <= n)
    printf("%d\\n", ans[1]);
  else
    puts("IMPOSSIBLE");
}
int main() {
  init();
  work();
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
#define LL long long
#define ri(a) scanf("%d", &a)
#define mem(a) memset(a, 0, sizeof(a))
using namespace std;
int n, m;
int step1, step2, step3;
int mapn[55][55];
int to[105][55][55];
struct NODE {
  int num;
  int v;
  NODE(int _num, int _v) : num(_num), v(_v) {}
  bool operator<(const NODE &a) { return num < a.num; }
};
void pre() {
  for (int i = 1; i <= n; i++) {
    to[0][i][i] = 1;
  }
  for (int i = 1; i <= 100; i++) {
    mem(to[i]);
    for (int j = 1; j <= n; j++) {
      for (int k = 1; k <= n; k++) {
        for (int t = 1; t <= n; t++) {
          to[i][j][k] += to[i - 1][j][t] * mapn[t][k];
        }
      }
    }
  }
}
queue<NODE> in;
int out[100];
map<int, int> o;
int main() {
  while (scanf("%d%d%d%d%d", &n, &m, &step1, &step2, &step3) != EOF) {
    mem(mapn);
    mem(out);
    for (int i = 1; i <= m; i++) {
      int a, b;
      ri(a);
      ri(b);
      mapn[a][b] = 1;
    }
    pre();
    for (int i = 1; i <= n; i++) {
      out[i] = 1;
    }
    in.push(NODE(1, 0));
    out[1] = 0;
    while (!in.empty()) {
      NODE temp = in.front();
      in.pop();
      if (o.find(temp.num) == o.end()) {
        o[temp.num] = temp.v;
      } else {
        o[temp.num] = min(o[temp.num], temp.v);
      }
      for (int i = 1; i <= n; i++) {
        if (to[step1][temp.num][i] == 1 && out[i]) {
          in.push(NODE(i, temp.v + 1));
        }
        if (to[step2][temp.num][i] == 1 && out[i]) {
          in.push(NODE(i, temp.v + 1));
        }
        if (to[step3][temp.num][i] == 1 && out[i]) {
          in.push(NODE(i, temp.v + 1));
        }
      }
    }
    printf("%d\\n", o[n]);
  }
}