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

#include <bits/stdc++.h>
using namespace std;

int n, m, a, b, c;

int main() {
  vector<int> w(3);
  cin >> n >> m >> w[0] >> w[1] >> w[2];
  sort(w.begin(), w.end());
  a = w[0], b = w[1], c = w[2];
  vector<vector<set<int>>> ls(n + 1, vector<set<int>>(101));
  for (int i = 0; i < m; i++) {
    int s, t;
    cin >> s >> t;
    ls[t][0].insert(s);
  }

  for (int i = 1; i <= c; i++) {
    for (int j = 1; j <= n; j++) {
      for (auto k : ls[j][i - 1]) {
        for (auto l : ls[k][0]) {
          ls[j][i].insert(l);
        }
      }
    }
  }

  set<int> slist;
  slist.insert(n);
  set<int> s;
  s.insert(n);
  vector<set<int>> touch(3);
  int turn = 0;
  bool flag = false;
  while (s.size()) {
    turn++;
    set<int> s_(s);
    s.clear();
    for (auto i : s_) {
      auto a_ = ls[i][a - 1];
      auto b_ = ls[i][b - 1];
      auto c_ = ls[i][c - 1];
      for (int j = 1; j <= n; j++) {
        if ((a_.find(j) != a_.end() || touch[0].find(j) != touch[0].end()) &&
            (b_.find(j) != b_.end() || touch[1].find(j) != touch[1].end()) &&
            (c_.find(j) != c_.end() || touch[2].find(j) != touch[2].end())) {
          if (slist.find(j) != slist.end())
            continue;
          slist.insert(j);
          s.insert(j);
        }
        if (a_.find(j) != a_.end())
          touch[0].insert(j);
        if (b_.find(j) != b_.end())
          touch[1].insert(j);
        if (c_.find(j) != c_.end())
          touch[2].insert(j);
      }
    }
    if (s.find(1) != s.end()) {
      flag = true;
      break;
    }
  }

  if (flag) {
    cout << turn << endl;
  } else {
    cout << "IMPOSSIBLE" << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

int n, m, a, b, c;

void dfs(int v, int d, vector<set<int>> &vec, set<int> &a_, set<int> &b_,
         set<int> &c_) {
  if (d == a)
    a_.insert(v);
  if (d == b)
    b_.insert(v);
  if (d == c) {
    c_.insert(v);
    return;
  }

  for (auto to : vec[v]) {
    dfs(to, d + 1, vec, a_, b_, c_);
  }
}

int main() {
  vector<int> w(3);
  cin >> n >> m >> w[0] >> w[1] >> w[2];
  sort(w.begin(), w.end());
  a = w[0], b = w[1], c = w[2];
  vector<set<int>> to(n + 1), rev(n + 1);
  for (int i = 0; i < m; i++) {
    int s, t;
    cin >> s >> t;
    to[s].insert(t);
    rev[t].insert(s);
  }

  set<int> slist;
  slist.insert(n);
  set<int> s;
  s.insert(n);
  vector<set<int>> touch(3);
  int turn = 0;
  bool flag = false;
  while (s.size()) {
    turn++;
    set<int> s_(s);
    s.clear();
    for (auto i : s_) {
      set<int> a_, b_, c_;
      dfs(i, 0, rev, a_, b_, c_);
      for (int j = 1; j <= n; j++) {
        if ((a_.find(j) != a_.end() || touch[0].find(j) != touch[0].end()) &&
            (b_.find(j) != b_.end() || touch[1].find(j) != touch[1].end()) &&
            (c_.find(j) != c_.end() || touch[2].find(j) != touch[2].end())) {
          if (slist.find(j) != slist.end())
            continue;
          slist.insert(j);
          s.insert(j);
        }
        if (a_.find(j) != a_.end())
          touch[0].insert(j);
        if (b_.find(j) != b_.end())
          touch[1].insert(j);
        if (c_.find(j) != c_.end())
          touch[2].insert(j);
      }
    }
    if (s.find(1) != s.end()) {
      flag = true;
      break;
    }
  }

  if (flag) {
    cout << turn << endl;
  } else {
    cout << "IMPOSSIBLE" << endl;
  }

  return 0;
}