Problem p03650 (C++)

Buggy submission (status: Runtime Error):
#include <iostream>
#include <map>
#include <vector>
using namespace std;
int N;
int P[200005];
int C[200005];
int Stack[200005];
bool Use[200005], Forest[200005];
vector<int> G[200005], Cycle, GG[200005];
bool ok, V[200005], cyc;
int Pos[200005], top;
int X[200005][2];
int DP[200005];
map<int, int> M[200005];
void Read() {
  cin >> N;
  for (int i = 1; i <= N; i++) {
    cin >> P[i];
    G[P[i]].push_back(i);
    GG[i].push_back(P[i]);
    GG[P[i]].push_back(i);
    M[P[i]][i]++;

    if (M[P[i]][i] == 1 && M[i].find(P[i]) != M[i].end()) {
      Cycle.push_back(i);
      Cycle.push_back(P[i]);
      cyc = 1;
    }
  }
}

void DFS(int node, int father) {
  Use[node] = 1;
  Stack[++top] = node;
  Pos[node] = top;
  for (int i = 0; i < GG[node].size(); i++) {
    int neighb = GG[node][i];
    if (neighb == father)
      continue;
    if (Use[neighb] == 0) {
      DFS(neighb, node);
    } else {
      if (Cycle.size() == 0)
        for (int j = Pos[neighb]; j <= top; j++)
          Cycle.push_back(Stack[j]), Forest[Stack[j]] = 1;
    }
  }
  --top;
}

void DFS2(int node) {

  for (int i = 0; i < G[node].size(); i++) {
    int neighb = G[node][i];
    if (Forest[neighb] == 1)
      continue;
    DFS2(neighb);
  }
  for (int i = 0; i < G[node].size() + 2; i++)
    V[i] = 0;
  for (int i = 0; i < G[node].size(); i++)
    if (Forest[G[node][i]] == 0)
      V[DP[G[node][i]]] = 1;
  int cnt = -1;
  for (int i = 0; i < G[node].size() + 2 && cnt < 1; i++)
    if (V[i] == 0)
      X[node][++cnt] = i;
  DP[node] = X[node][0];
}

void DFS3(int val, int node) {
  int x = P[node];
  DP[node] = val;
  while (x != node) {
    for (int i = 0; i < G[x].size() + 2; i++)
      V[i] = 0;
    for (int i = 0; i < G[x].size(); i++)
      V[DP[G[x][i]]] = 1;
    int cnt = -1;
    for (int i = 0; i < G[x].size() + 2; i++)
      if (V[i] == 0) {
        DP[x] = i;
        break;
      }
    x = P[x];
  }
}

bool check() {
  for (int node = 1; node <= N; node++) {
    for (int i = 0; i < G[node].size() + 2; i++)
      V[i] = 0;
    for (int i = 0; i < G[node].size(); i++)
      V[DP[G[node][i]]] = 1;
    int cnt = -1;
    for (int i = 0; i < G[node].size() + 2; i++)
      if (V[i] == 0) {
        if (i < DP[node])
          return 0;
      }
    if (V[DP[node]] == 1)
      return 0;
  }
  return 1;
}
int main() {
  Read();
  if (N == 2) {
    cout << "POSSIBLE\n";
    return 0;
  }
  if (cyc == 0)
    DFS(1, 0);
  for (int i = 0; i < Cycle.size(); i++)
    DFS2(Cycle[i]);
  DFS3(X[Cycle[0]][0], Cycle[0]);
  int ans = check();
  DFS3(X[Cycle[0]][1], Cycle[0]);
  ans = max(ans, (int)check());
  if (ans == 1)
    cout << "POSSIBLE\n";
  else
    cout << "IMPOSSIBLE\n";
  return 0;
}


Fixed submission:
#include <iostream>
#include <map>
#include <vector>
using namespace std;
int N;
int P[200005];
int C[200005];
int Stack[200005];
bool Use[200005], Forest[200005];
vector<int> G[200005], Cycle, GG[200005];
bool ok, V[200005], cyc;
int Pos[200005], top;
int X[200005][2];
int DP[200005];
map<int, int> M[200005];
void Read() {
  cin >> N;
  for (int i = 1; i <= N; i++) {
    cin >> P[i];
    G[P[i]].push_back(i);
    GG[i].push_back(P[i]);
    GG[P[i]].push_back(i);
    M[P[i]][i]++;

    if (M[P[i]][i] == 1 && M[i].find(P[i]) != M[i].end()) {
      Cycle.push_back(i);
      Cycle.push_back(P[i]);
      cyc = 1;
      Forest[i] = Forest[P[i]] = 1;
    }
  }
}

void DFS(int node, int father) {
  Use[node] = 1;
  Stack[++top] = node;
  Pos[node] = top;
  for (int i = 0; i < GG[node].size(); i++) {
    int neighb = GG[node][i];
    if (neighb == father)
      continue;
    if (Use[neighb] == 0) {
      DFS(neighb, node);
    } else {
      if (Cycle.size() == 0)
        for (int j = Pos[neighb]; j <= top; j++)
          Cycle.push_back(Stack[j]), Forest[Stack[j]] = 1;
    }
  }
  --top;
}

void DFS2(int node) {

  for (int i = 0; i < G[node].size(); i++) {
    int neighb = G[node][i];
    if (Forest[neighb] == 1)
      continue;
    DFS2(neighb);
  }
  for (int i = 0; i < G[node].size() + 2; i++)
    V[i] = 0;
  for (int i = 0; i < G[node].size(); i++)
    if (Forest[G[node][i]] == 0)
      V[DP[G[node][i]]] = 1;
  int cnt = -1;
  for (int i = 0; i < G[node].size() + 2 && cnt < 1; i++)
    if (V[i] == 0)
      X[node][++cnt] = i;
  DP[node] = X[node][0];
}

void DFS3(int val, int node) {
  int x = P[node];
  DP[node] = val;
  while (x != node) {
    for (int i = 0; i < G[x].size() + 2; i++)
      V[i] = 0;
    for (int i = 0; i < G[x].size(); i++)
      V[DP[G[x][i]]] = 1;
    int cnt = -1;
    for (int i = 0; i < G[x].size() + 2; i++)
      if (V[i] == 0) {
        DP[x] = i;
        break;
      }
    x = P[x];
  }
}

bool check() {
  for (int node = 1; node <= N; node++) {
    for (int i = 0; i < G[node].size() + 2; i++)
      V[i] = 0;
    for (int i = 0; i < G[node].size(); i++)
      V[DP[G[node][i]]] = 1;
    int cnt = -1;
    for (int i = 0; i < G[node].size() + 2; i++)
      if (V[i] == 0) {
        if (i < DP[node])
          return 0;
      }
    if (V[DP[node]] == 1)
      return 0;
  }
  return 1;
}
int main() {
  Read();
  if (N == 2) {
    cout << "POSSIBLE\n";
    return 0;
  }
  if (cyc == 0)
    DFS(1, 0);
  for (int i = 0; i < Cycle.size(); i++)
    DFS2(Cycle[i]);
  DFS3(X[Cycle[0]][0], Cycle[0]);
  int ans = check();
  DFS3(X[Cycle[0]][1], Cycle[0]);
  ans = max(ans, (int)check());
  if (ans == 1)
    cout << "POSSIBLE\n";
  else
    cout << "IMPOSSIBLE\n";
  return 0;
}