Problem p02366 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, n) FOR(i, 0, n)
#define rep(i, n) FOR(i, 0, n)
#define DEBUG(x) cout << #x << ": " << x << endl
#define vint vector<int>
#define vdouble vector<double>
#define vstring vector<string>
using namespace std;

#include <map>
#include <queue>
#include <set>

typedef long long ll;
typedef unsigned long long ull;

const int MAX_N = 1000000;
static const int INFTY = (1 << 21);

class Edge {
public:
  int from, to, cost;
  int backedge;
  Edge(int from = 0, int to = 0, int cost = 0)
      : from(from), to(to), cost(cost) {
    backedge = -1;
  }
};

class Node {
public:
  vector<Edge> edges;
  int prenum;
  int parent;
  int lowest;
  Node() {
    prenum = -1;
    parent = -1;
  }
};

class Graph {
public:
  vector<Node> nodes;
  int prenum;
  Graph(int n) {
    rep(i, n) {
      Node n;
      nodes.push_back(n);
    }
    prenum = 0;
  }
};

Graph G(0);

void dfs(Edge &e) {

  Node &n = G.nodes[e.to];

  if (n.prenum != -1) {
    int parent = G.nodes[e.from].parent;
    if (e.to == parent) {
      e.backedge = -1; // neither backedge nor treeedge
    } else {
      e.backedge = 1;
    }
    return;
  }

  // set parameter
  G.prenum++;
  e.backedge = 0; // not backage
  n.prenum = G.prenum;
  n.parent = e.from;
  n.lowest = n.prenum;

  for (auto &ee : n.edges) {
    dfs(ee);
  }

  for (auto &ee : n.edges) {
    if (ee.backedge != -1) {
      n.lowest = min(n.lowest, G.nodes[ee.to].lowest);
    }
  }
}

int main() {

  int V, E;
  cin >> V >> E;

  G = Graph(V);

  rep(i, E) {
    int from, to;
    cin >> from >> to;
    G.nodes[from].edges.push_back(Edge(from, to, 0));
    G.nodes[to].edges.push_back(Edge(to, from, 0));
  }

  Edge e(-1, 0, 0);
  dfs(e);

  rep(i, V) {
    // printf("%d %d %d %d\\n", i, G.nodes[i].parent, G.nodes[i].prenum,
    // G.nodes[i].lowest);
  }

  set<int> ret;
  rep(i, V) {
    if (G.nodes[i].parent == -1) {
      int count = 0;
      rep(j, V) {
        if (G.nodes[j].parent == i)
          count++;
      }
      if (count > 1)
        ret.insert(i);
    } else {
      Node n = G.nodes[i];
      Node p = G.nodes[n.parent];
      if (p.prenum <= n.lowest && p.parent != -1) {
        ret.insert(n.parent);
      }
    }
  }

  for (auto &i : ret) {
    cout << i << endl;
  }
}

Error: -11

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, n) FOR(i, 0, n)
#define rep(i, n) FOR(i, 0, n)
#define DEBUG(x) cout << #x << ": " << x << endl
#define vint vector<int>
#define vdouble vector<double>
#define vstring vector<string>
using namespace std;

#include <map>
#include <queue>
#include <set>

typedef long long ll;
typedef unsigned long long ull;

const int MAX_N = 1000000;
static const int INFTY = (1 << 21);

class Edge {
public:
  int from, to, cost;
  int backedge;
  Edge(int from = 0, int to = 0, int cost = 0)
      : from(from), to(to), cost(cost) {
    backedge = -1;
  }
};

class Node {
public:
  vector<Edge> edges;
  int prenum;
  int parent;
  int lowest;
  Node() {
    prenum = -1;
    parent = -1;
  }
};

class Graph {
public:
  vector<Node> nodes;
  int prenum;
  Graph(int n) {
    rep(i, n) {
      Node n;
      nodes.push_back(n);
    }
    prenum = 0;
  }
};

Graph *GG = NULL;
Graph &G = *GG;

void dfs(Edge &e) {

  Node *n = &(G.nodes[e.to]);

  if (n->prenum != -1) {
    int parent = G.nodes[e.from].parent;
    if (e.to == parent) {
      e.backedge = -1; // neither backedge nor treeedge
    } else {
      e.backedge = 1;
    }
    return;
  }

  // set parameter
  G.prenum++;
  e.backedge = 0; // not backage
  n->prenum = G.prenum;
  n->parent = e.from;
  n->lowest = n->prenum;

  for (auto &ee : n->edges) {
    dfs(ee);
  }

  for (auto &ee : n->edges) {
    if (ee.backedge != -1) {
      n->lowest = min(n->lowest, G.nodes[ee.to].lowest);
    }
  }
}

int main() {

  int V, E;
  cin >> V >> E;

  Graph _G(V);
  GG = &_G;

  rep(i, E) {
    int from, to;
    cin >> from >> to;
    G.nodes[from].edges.push_back(Edge(from, to, 0));
    G.nodes[to].edges.push_back(Edge(to, from, 0));
  }

  Edge e(-1, 0, 0);
  dfs(e);

  rep(i, V) {
    // printf("%d %d %d %d\\n", i, G.nodes[i].parent, G.nodes[i].prenum,
    // G.nodes[i].lowest);
  }

  set<int> ret;
  rep(i, V) {
    if (G.nodes[i].parent == -1) {
      int count = 0;
      rep(j, V) {
        if (G.nodes[j].parent == i)
          count++;
      }
      if (count > 1)
        ret.insert(i);
    } else {
      Node n = G.nodes[i];
      Node p = G.nodes[n.parent];
      if (p.prenum <= n.lowest && p.parent != -1) {
        ret.insert(n.parent);
      }
    }
  }

  for (auto &i : ret) {
    cout << i << endl;
  }
}