Problem p02902 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

/*
result can always be reduced to a cycle

lets say we have a cycle, i posit that even if there are extra stuff, we can
still reduce it

extra forward edge-> we can take one of the two

dfs down -> find a cycle (if none then no answer)

run through the elements in the cycle, chopping off ones

run through once-> establish a set & order.
run again, checking if the set has extra edge, if so, chop it off and repeat

*/

const int N = 1000;
int n, m;
vector<int> g[N];

vector<int> reduce_cycle(vector<int> v) {
  vector<int> res = v;
  int in[N] = {};
  int cnt = 1;
  for (int e : v) {
    in[e] = cnt++;
  }
  int len = v.size();
  for (int i = 0; i < v.size(); ++i) {
    int e = v[i];
    for (int to : g[e]) {
      if (to == v[(i + 1) % len])
        continue;
      if (in[to]) { // chop it off
        vector<int> nxt;
        if (in[e] < in[to]) {
          nxt.assign(res.begin(), res.begin() + in[e]);
          nxt.insert(nxt.end(), res.begin() + in[to] - 1, res.end());
        } else {
          nxt.assign(res.begin() + in[to] - 1, res.begin() + in[e]);
        }
        res.swap(nxt);
        return reduce_cycle(res);
      }
    }
  }
  return res;
}

int col[N];

vector<int> find_cycle(int cur, vector<int> &path) {
  path.push_back(cur);
  col[cur] = 1;
  vector<int> res;
  for (int a : g[cur]) {
    if (col[a] == 1) {
      auto it = find(path.begin(), path.end(), a);
      assert(it != path.end());
      res.assign(it, path.end());
    } else {
      res = find_cycle(a, path);
    }

    if (res.size())
      break;
  }
  path.pop_back();
  col[cur] = 2;
  return res;
}

int main() {
  cin.tie(0);
  cout.tie(0);
  ios_base::sync_with_stdio(0);
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    int x, y;
    cin >> x >> y;
    g[x].push_back(y);
  }
  vector<int> ans;
  for (int i = 1; i <= n; ++i) {
    if (!col[i]) {
      vector<int> path;
      auto res = find_cycle(i, path);
      if (res.size()) {
        ans = reduce_cycle(res);
        break;
      }
    }
  }
  if (ans.size()) {
    cout << ans.size() << '\n';
    for (int a : ans) {
      cout << a << '\n';
    }
  } else {
    cout << -1 << '\n';
  }
}


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

/*
result can always be reduced to a cycle

lets say we have a cycle, i posit that even if there are extra stuff, we can
still reduce it

extra forward edge-> we can take one of the two

dfs down -> find a cycle (if none then no answer)

run through the elements in the cycle, chopping off ones

run through once-> establish a set & order.
run again, checking if the set has extra edge, if so, chop it off and repeat

*/

const int N = 1000 + 5;
int n, m;
vector<int> g[N];

vector<int> reduce_cycle(vector<int> v) {
  vector<int> res = v;
  int in[N] = {};
  int cnt = 1;
  for (int e : v) {
    in[e] = cnt++;
  }
  int len = v.size();
  for (int i = 0; i < v.size(); ++i) {
    int e = v[i];
    for (int to : g[e]) {
      if (to == v[(i + 1) % len])
        continue;
      if (in[to]) { // chop it off
        vector<int> nxt;
        if (in[e] < in[to]) {
          nxt.assign(res.begin(), res.begin() + in[e]);
          nxt.insert(nxt.end(), res.begin() + in[to] - 1, res.end());
        } else {
          nxt.assign(res.begin() + in[to] - 1, res.begin() + in[e]);
        }
        res.swap(nxt);
        return reduce_cycle(res);
      }
    }
  }
  return res;
}

int col[N];

vector<int> find_cycle(int cur, vector<int> &path) {
  path.push_back(cur);
  col[cur] = 1;
  vector<int> res;
  for (int a : g[cur]) {
    if (col[a] == 1) {
      auto it = find(path.begin(), path.end(), a);
      assert(it != path.end());
      res.assign(it, path.end());
    } else {
      res = find_cycle(a, path);
    }

    if (res.size())
      break;
  }
  path.pop_back();
  col[cur] = 2;
  return res;
}

int main() {
  cin.tie(0);
  cout.tie(0);
  ios_base::sync_with_stdio(0);
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    int x, y;
    cin >> x >> y;
    g[x].push_back(y);
  }
  vector<int> ans;
  for (int i = 1; i <= n; ++i) {
    if (!col[i]) {
      vector<int> path;
      auto res = find_cycle(i, path);
      if (res.size()) {
        ans = reduce_cycle(res);
        break;
      }
    }
  }
  if (ans.size()) {
    cout << ans.size() << '\n';
    for (int a : ans) {
      cout << a << '\n';
    }
  } else {
    cout << -1 << '\n';
  }
}