Problem p02367 (C++)

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

#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, a, b) for (int i = (a); i < (b); i++)
#define rrep(i, n) for (int i = (n)-1; i >= 0; i--)
#define rrep2(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define printV(v)                                                              \
  for (auto &&x : v) {                                                         \
    cerr << x << " ";                                                          \
  }                                                                            \
  cerr << endl
#define printVV(vv)                                                            \
  for (auto &&v : vv) {                                                        \
    for (auto &&x : v) {                                                       \
      cerr << x << " ";                                                        \
    }                                                                          \
    cerr << endl;                                                              \
  }
#define printP(p) cerr << p.first << " " << p.second << endl
#define printVP(vp)                                                            \
  for (auto &&p : vp)                                                          \
    printP(p);

typedef long long ll;
typedef pair<int, int> Pii;
typedef tuple<int, int, int> TUPLE;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<Pii> vp;
const int inf = 1e9;
const int mod = 1e9 + 7;
typedef vector<vector<int>> Graph;
typedef pair<int, int> Edge; // (a < b: undirected)

class BICC {
private:
  const int n;

  Graph G;
  vi depth;
  vi par;
  map<Edge, int> imosEdge;
  map<Edge, int> EdgeType;
  enum { UNUSED, USED_DFS, BRIDGE };
  vector<Edge> bridges;

  vi cmp;
  int num_cc;
  vi size_of_vertex;
  Graph G_cc;

public:
  BICC(int _n)
      : n(_n), G(_n), depth(_n, -1), par(_n, -1), cmp(_n, -1), num_cc(0) {}
  Edge getEdge(int a, int b) {
    if (a > b)
      swap(a, b);
    return Edge(a, b);
  }
  void updateEdgeType(int a, int b, int type) {
    if (a < 0 || b < 0)
      return;
    EdgeType[getEdge(a, b)] = type;
  }
  void addEdge(int a, int b) {
    G[a].emplace_back(b);
    G[b].emplace_back(a);
    updateEdgeType(a, b, UNUSED);
  }
  void dfsTreeConstruct(int v, int pre) {
    if (depth[v] != -1)
      return;
    depth[v] = (pre == -1 ? 0 : depth[pre] + 1);
    par[v] = pre;
    updateEdgeType(pre, v, USED_DFS);
    for (auto &&nxt : G[v]) {
      if (nxt != pre)
        dfsTreeConstruct(nxt, v);
    }
  }
  void updateImos(int a, int b) {
    if (depth[a] < depth[b])
      swap(a, b);

    if (par[a] != -1) {
      imosEdge[getEdge(a, par[a])]++;
    }
    if (par[b] != -1) {
      imosEdge[getEdge(b, par[b])]--;
    }
  }
  int imosFinal(int v, int pre) {
    int t = 0;
    for (auto &&nxt : G[v]) {
      if (nxt != pre && EdgeType[getEdge(nxt, v)] == USED_DFS) {
        t += imosFinal(nxt, v);
      }
    }
    if (pre != -1)
      imosEdge[getEdge(v, pre)] += t;
    return pre == -1 ? 0 : imosEdge[getEdge(v, pre)];
  }
  int extractCC(int v, int color) {
    if (cmp[v] != -1)
      return 0;
    cmp[v] = color;
    int t = 1;
    for (auto &&nxt : G[v]) {
      if (EdgeType[getEdge(v, nxt)] != BRIDGE) {
        t += extractCC(nxt, color);
      }
    }
    return t;
  }
  void bicc() {
    dfsTreeConstruct(0, -1);
    for (auto &&p : EdgeType) {
      Edge e;
      int type;
      tie(e, type) = p;
      if (type == UNUSED) {
        updateImos(e.first, e.second);
      }
    }
    imosFinal(0, -1);
    for (auto &&p : EdgeType) {
      Edge e;
      int type;
      tie(e, type) = p;
      if (type == USED_DFS) {
        if (imosEdge[e] == 0) {
          EdgeType[e] = BRIDGE;
          bridges.emplace_back(e);
        }
      }
    }

    // rep(i, n) {
    // 	int size_cc = extractCC(i, num_cc);
    // 	if (size_cc > 0) {
    // 		size_of_vertex.emplace_back(size_cc);
    // 		num_cc++;
    // 	}
    // }
    //
    // r<set<int>> G_cc_st(num_cc);
    // for (auto&& p : EdgeType) {
    //     Edge e;
    //     int type;
    //     tie(e, type) = p;
    //     if (type == BRIDGE) {
    // 		G_cc_st[cmp[e.first]].insert(cmp[e.second]);
    // 		G_cc_st[cmp[e.second]].insert(cmp[e.first]);
    //     }
    // }
    //
    // rep(i, num_cc) {
    // 	G_cc.emplace_back(vector<int>(all(G_cc_st[i])));
    // }
  }
  vector<Edge> getBridges() { return bridges; }
};

signed main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);

  int V, E;
  cin >> V >> E;
  BICC bicc(V);
  rep(i, E) {
    int a, b;
    cin >> a >> b;
    bicc.addEdge(a, b);
  }

  bicc.bicc();
  auto bridges = bicc.getBridges();
  printVP(bridges);
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define int long long // <-----!!!!!!!!!!!!!!!!!!!

#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, a, b) for (int i = (a); i < (b); i++)
#define rrep(i, n) for (int i = (n)-1; i >= 0; i--)
#define rrep2(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define printV(v)                                                              \
  for (auto &&x : v) {                                                         \
    cerr << x << " ";                                                          \
  }                                                                            \
  cerr << endl
#define printVV(vv)                                                            \
  for (auto &&v : vv) {                                                        \
    for (auto &&x : v) {                                                       \
      cerr << x << " ";                                                        \
    }                                                                          \
    cerr << endl;                                                              \
  }
#define printP(p) cerr << p.first << " " << p.second << endl
#define printVP(vp)                                                            \
  for (auto &&p : vp)                                                          \
    printP(p);

typedef long long ll;
typedef pair<int, int> Pii;
typedef tuple<int, int, int> TUPLE;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<Pii> vp;
const int inf = 1e9;
const int mod = 1e9 + 7;
typedef vector<vector<int>> Graph;
typedef pair<int, int> Edge; // (a < b: undirected)

class BICC {
private:
  const int n;

  Graph G;
  vi depth;
  vi par;
  map<Edge, int> imosEdge;
  map<Edge, int> EdgeType;
  enum { UNUSED, USED_DFS, BRIDGE };
  vector<Edge> bridges;

  vi cmp;
  int num_cc;
  vi size_of_vertex;
  Graph G_cc;

public:
  BICC(int _n)
      : n(_n), G(_n), depth(_n, -1), par(_n, -1), cmp(_n, -1), num_cc(0) {}
  Edge getEdge(int a, int b) {
    if (a > b)
      swap(a, b);
    return Edge(a, b);
  }
  void updateEdgeType(int a, int b, int type) {
    if (a < 0 || b < 0)
      return;
    EdgeType[getEdge(a, b)] = type;
  }
  void addEdge(int a, int b) {
    G[a].emplace_back(b);
    G[b].emplace_back(a);
    updateEdgeType(a, b, UNUSED);
  }
  void dfsTreeConstruct(int v, int pre) {
    if (depth[v] != -1)
      return;
    depth[v] = (pre == -1 ? 0 : depth[pre] + 1);
    par[v] = pre;
    updateEdgeType(pre, v, USED_DFS);
    for (auto &&nxt : G[v]) {
      if (nxt != pre)
        dfsTreeConstruct(nxt, v);
    }
  }
  void updateImos(int a, int b) {
    if (depth[a] < depth[b])
      swap(a, b);

    if (par[a] != -1) {
      imosEdge[getEdge(a, par[a])]++;
    }
    if (par[b] != -1) {
      imosEdge[getEdge(b, par[b])]--;
    }
  }
  int imosFinal(int v, int pre) {
    int t = 0;
    for (auto &&nxt : G[v]) {
      if (nxt != pre && EdgeType[getEdge(nxt, v)] == USED_DFS) {
        t += imosFinal(nxt, v);
      }
    }
    if (pre != -1)
      imosEdge[getEdge(v, pre)] += t;
    return pre == -1 ? 0 : imosEdge[getEdge(v, pre)];
  }
  int extractCC(int v, int color) {
    if (cmp[v] != -1)
      return 0;
    cmp[v] = color;
    int t = 1;
    for (auto &&nxt : G[v]) {
      if (EdgeType[getEdge(v, nxt)] != BRIDGE) {
        t += extractCC(nxt, color);
      }
    }
    return t;
  }
  void bicc() {
    dfsTreeConstruct(0, -1);
    for (auto &&p : EdgeType) {
      Edge e;
      int type;
      tie(e, type) = p;
      if (type == UNUSED) {
        updateImos(e.first, e.second);
      }
    }
    imosFinal(0, -1);
    for (auto &&p : EdgeType) {
      Edge e;
      int type;
      tie(e, type) = p;
      if (type == USED_DFS) {
        if (imosEdge[e] == 0) {
          EdgeType[e] = BRIDGE;
          bridges.emplace_back(e);
        }
      }
    }

    // rep(i, n) {
    // 	int size_cc = extractCC(i, num_cc);
    // 	if (size_cc > 0) {
    // 		size_of_vertex.emplace_back(size_cc);
    // 		num_cc++;
    // 	}
    // }
    //
    // r<set<int>> G_cc_st(num_cc);
    // for (auto&& p : EdgeType) {
    //     Edge e;
    //     int type;
    //     tie(e, type) = p;
    //     if (type == BRIDGE) {
    // 		G_cc_st[cmp[e.first]].insert(cmp[e.second]);
    // 		G_cc_st[cmp[e.second]].insert(cmp[e.first]);
    //     }
    // }
    //
    // rep(i, num_cc) {
    // 	G_cc.emplace_back(vector<int>(all(G_cc_st[i])));
    // }
  }
  vector<Edge> getBridges() { return bridges; }
};

signed main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);

  int V, E;
  cin >> V >> E;
  BICC bicc(V);
  rep(i, E) {
    int a, b;
    cin >> a >> b;
    bicc.addEdge(a, b);
  }

  bicc.bicc();
  auto bridges = bicc.getBridges();
  // printVP(bridges);
  for (auto &&e : bridges) {
    cout << e.first << " " << e.second << endl;
  }
}