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

#include <bits/stdc++.h>

using namespace std;

struct UnionFind {
  vector<int> data;

  UnionFind(int sz) { data.assign(sz, -1); }

  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return (false);
    if (data[x] > data[y])
      swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return (true);
  }

  int find(int k) {
    if (data[k] < 0)
      return (k);
    return (data[k] = find(data[k]));
  }

  int size(int k) { return (-data[find(k)]); }
};

struct LowLink {
  UnionFind uf;
  vector<vector<int>> g;
  vector<int> used, ord, low, parent;

  LowLink(size_t v) : g(v), used(v, 0), ord(v), low(v), uf(v), parent(v, -1) {}

  virtual void add_edge(int x, int y) {
    g[x].push_back(y);
    g[y].push_back(x);
  }

  void dfs(int idx, int &k, int par = -1) {
    used[idx] = true;
    ord[idx] = k++;
    low[idx] = ord[idx];

    for (auto &to : g[idx]) {
      if (!used[to]) {
        dfs(to, k, idx);
        low[idx] = min(low[idx], low[to]);
        parent[to] = idx;
        if (ord[idx] >= low[to])
          uf.unite(idx, to);
      } else if (to != par) {
        low[idx] = min(low[idx], ord[to]);
      }
    }
  }

  void dfs() {
    int k = 0;
    for (int i = 0; i < g.size(); i++) {
      if (used[i])
        continue;
      dfs(i, k);
    }
  }
};

struct BiConnectedComponents : LowLink {
  vector<pair<int, int>> edges;
  vector<int> comp;

  BiConnectedComponents(size_t v) : LowLink(v), comp(v) {}

  void add_edge(int x, int y) {
    LowLink::add_edge(x, y);
    edges.push_back(minmax(x, y));
  }

  int operator[](int k) { return (comp[k]); }

  vector<pair<int, int>> build(vector<vector<int>> &t) {
    LowLink::dfs();
    int ptr = 0;
    vector<int> cc(g.size());
    for (int i = 0; i < g.size(); i++) {
      if (i == uf.find(i))
        cc[i] = ptr++;
    }

    t.resize(ptr);
    for (int i = 0; i < g.size(); i++) {
      comp[i] = cc[uf.find(i)];
    }
    vector<pair<int, int>> vs;
    for (auto &e : edges) {
      int x = comp[e.first], y = comp[e.second];
      if (x == y)
        continue;
      vs.emplace_back(e.first, e.second);
      t[x].push_back(y);
      t[y].push_back(x);
    }
    sort(begin(vs), end(vs));
    return (vs);
  }
};

vector<vector<int>> g;
int sz[100000];
int dp[2][100000];

void dfs(int idx, int par) {
  dp[0][idx] = 0;
  dp[1][idx] = sz[idx];
  for (auto &to : g[idx]) {
    if (to == par)
      continue;
    dfs(to, idx);
    dp[0][idx] += max(dp[0][to], dp[1][to]);
    dp[1][idx] += dp[0][to];
  }
}

int main() {
  int N, M;
  scanf("%d %d", &N, &M);
  BiConnectedComponents graph(N);
  for (int i = 0; i < M; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    graph.add_edge(a, b);
  }
  graph.build(g);

  for (int i = 0; i < N; i++)
    ++sz[graph[i]];
  int ret = 0;

  memset(dp, -1, sizeof(dp));
  for (int i = 0; i < g.size(); i++) {
    if (~dp[0][i])
      continue;
    dfs(i, -1);
    ret += max(dp[0][i], dp[1][i]);
  }
  printf("%d\\n", ret);
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

struct UnionFind {
  vector<int> data;

  UnionFind(int sz) { data.assign(sz, -1); }

  bool unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y)
      return (false);
    if (data[x] > data[y])
      swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return (true);
  }

  int find(int k) {
    if (data[k] < 0)
      return (k);
    return (data[k] = find(data[k]));
  }

  int size(int k) { return (-data[find(k)]); }
};

struct LowLink {
  UnionFind uf;
  vector<vector<int>> g;
  vector<int> used, ord, low, parent;

  LowLink(size_t v) : g(v), used(v, 0), ord(v), low(v), uf(v), parent(v, -1) {}

  virtual void add_edge(int x, int y) {
    g[x].push_back(y);
    g[y].push_back(x);
  }

  void dfs(int idx, int &k, int par = -1) {
    used[idx] = true;
    ord[idx] = k++;
    low[idx] = ord[idx];

    for (auto &to : g[idx]) {
      if (!used[to]) {
        dfs(to, k, idx);
        low[idx] = min(low[idx], low[to]);
        parent[to] = idx;
        if (ord[idx] >= low[to])
          uf.unite(idx, to);
      } else if (to != par) {
        low[idx] = min(low[idx], ord[to]);
      }
    }
  }

  void dfs() {
    int k = 0;
    for (int i = 0; i < g.size(); i++) {
      if (used[i])
        continue;
      dfs(i, k);
    }
  }
};

struct BiConnectedComponents : LowLink {
  vector<pair<int, int>> edges;
  vector<int> comp;

  BiConnectedComponents(size_t v) : LowLink(v), comp(v) {}

  void add_edge(int x, int y) {
    LowLink::add_edge(x, y);
    edges.push_back(minmax(x, y));
  }

  int operator[](int k) { return (comp[k]); }

  vector<pair<int, int>> build(vector<vector<int>> &t) {
    LowLink::dfs();
    int ptr = 0;
    vector<int> cc(g.size());
    for (int i = 0; i < g.size(); i++) {
      if (i == uf.find(i))
        cc[i] = ptr++;
    }

    t.resize(ptr);
    for (int i = 0; i < g.size(); i++) {
      comp[i] = cc[uf.find(i)];
    }
    vector<pair<int, int>> vs;
    for (auto &e : edges) {
      int x = comp[e.first], y = comp[e.second];
      if (x == y)
        continue;
      vs.emplace_back(e.first, e.second);
      t[x].push_back(y);
      t[y].push_back(x);
    }
    sort(begin(vs), end(vs));
    return (vs);
  }
};

vector<vector<int>> g;
int sz[100000];
int dp[2][100000];

void dfs(int idx, int par) {
  dp[0][idx] = 0;
  dp[1][idx] = sz[idx];
  for (auto &to : g[idx]) {
    if (to == par)
      continue;
    dfs(to, idx);
    dp[0][idx] += max(dp[0][to], dp[1][to]);
    dp[1][idx] += dp[0][to];
  }
}

int main() {
  int N, M;
  scanf("%d %d", &N, &M);
  BiConnectedComponents graph(N);
  for (int i = 0; i < M; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    graph.add_edge(a, b);
  }
  graph.build(g);
  for (int i = 0; i < N; i++)
    ++sz[graph[i]];
  int ret = 0;
  memset(dp, -1, sizeof(dp));
  for (int i = 0; i < g.size(); i++) {
    if (~dp[i][0])
      continue;
    dfs(i, -1);
    ret += max(dp[0][i], dp[1][i]);
  }
  printf("%d\\n", ret);
}