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

#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x) cerr << #x << " = " << (x) << endl;
using namespace std;

template <typename T> ostream &operator<<(ostream &os, vector<T> &v) {
  rep(i, v.size()) { os << v[i] << (i == v.size() - 1 ? "" : " "); }
  return os;
}
template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &x : v) {
    is >> x;
  }
  return is;
}

void dfs(vector<vector<int>> &g, vector<int> &in, vector<bool> &used, int pos,
         vector<bool> &p) {
  used[pos] = true;
  for (auto to : g[pos]) {
    if (used[to])
      continue;
    dfs(g, in, used, to, p);
  }
  if (in[pos] == 1 and pos != 0) {
    for (auto i : g[pos]) {
      in[i]--;
    }
    p[pos] = true;
  }
}

int bfs(vector<vector<int>> &g, vector<bool> &used, vector<int> &w) {
  int n = g.size();

  queue<int> q;
  rep(i, n) {
    if (not used[i])
      q.emplace(i);
  }

  vector<int> dis(n, 0);
  while (not q.empty()) {
    int pos = q.front();
    q.pop();
    for (auto to : g[pos]) {
      if (not used[to])
        continue;
      used[to] = false;
      dis[to] = dis[pos] + w[to];
      q.emplace(to);
    }
  }

  return *max_element(all(dis));
}

int main() {
  int n, m;
  cin >> n >> m;

  vector<int> w(n);
  cin >> w;

  vector<vector<int>> g(n);
  rep(i, m) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    g[a].emplace_back(b);
    g[b].emplace_back(a);
  }

  vector<int> in(n);
  rep(i, n) in[i] = g[i].size();

  vector<bool> p(n, 0);
  vector<bool> used(n, 0);
  dfs(g, in, used, 0, p);

  int res = 0;
  rep(i, n) {
    if (not p[i])
      res += w[i];
  }

  cout << bfs(g, p, w) + res << endl;
}


Error: 0
ans = 21


Fixed submission:

#include <bits/stdc++.h>
#define range(i, a, b) for (int i = (a); i < (b); i++)
#define rep(i, b) for (int i = 0; i < (b); i++)
#define all(a) (a).begin(), (a).end()
#define show(x) cerr << #x << " = " << (x) << endl;
using namespace std;

template <typename T> ostream &operator<<(ostream &os, vector<T> &v) {
  rep(i, v.size()) { os << v[i] << (i == v.size() - 1 ? "" : " "); }
  return os;
}
template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  for (T &x : v) {
    is >> x;
  }
  return is;
}

class Node {
public:
  int ord; // DFSの訪問の順番
  int par; // DFS Treeにおける親
  int low; // min(自分のord, 逆辺がある場合の親のord, すべての子のlow)
  Node() : ord(-1) {}
};

class ArticulationPoints {
private:
  int v, cnt;
  vector<Node> node;
  void dfs(int cur, int prev) {
    node[cur].ord = node[cur].low = cnt;
    cnt++;

    for (auto to : g[cur]) {
      if (to == prev)
        continue;
      if (node[to].ord >= 0) {
        node[cur].low = min(node[cur].low, node[to].ord);
      } else {
        node[to].par = cur;
        dfs(to, cur);
        node[cur].low = min(node[cur].low, node[to].low);
      }
      if (node[cur].ord < node[to].low) {
        bridge.emplace_back(min(cur, to), max(cur, to));
      }
    }
  }

public:
  vector<vector<int>> g;
  vector<pair<int, int>> bridge;
  set<int> ap; // 関節店
  ArticulationPoints(int n) : v(n), cnt(1), node(n), g(n) {}
  void addEdge(int a, int b) {
    g[a].emplace_back(b);
    g[b].emplace_back(a);
  }
  bool isBridge(int u, int v) {
    if (node[u].ord > node[v].ord)
      swap(u, v);
    return node[u].ord < node[v].low;
  }
  void run() {
    dfs(0, -1); // 0 = root

    int np = 0;
    range(i, 1, v) {
      int p = node[i].par;
      if (p == 0)
        np++;
      else if (node[p].ord <= node[i].low)
        ap.emplace(p);
    }
    if (np > 1)
      ap.emplace(0);
    sort(all(bridge));
    // for(auto it:ap){ cout << it << endl; } //関節点の全列挙
    // for(auto it:bridge){ cout << it.first << ' ' << it.second << endl; }
    // //橋の全列挙
  }
};

class TwoEdgeConnectedComponent : public ArticulationPoints {
private:
  void dfs(int c, int pos) {
    ver[c].emplace_back(pos);
    comp[pos] = c;
    for (int to : g[pos]) {
      if (comp[to] >= 0)
        continue;
      if (isBridge(pos, to))
        continue;
      dfs(c, to);
    }
  }
  void addComp(int pos) {
    if (comp[pos] >= 0)
      return;
    ver.emplace_back();
    dfs(ver.size() - 1, pos);
  }

public:
  vector<int> comp; // 成分分解前の頂点から分解後の頂点への写像？
  vector<vector<int>> ver; // 分解後の頂点と、その頂点に含まれる分解前の頂点
  TwoEdgeConnectedComponent(int n) : ArticulationPoints(n), comp(n, -1) {}
  void solve() {
    run();
    for (auto p : bridge) {
      addComp(p.first);
      addComp(p.second);
    }
    addComp(0);
  }
  vector<vector<int>> getTree() {
    vector<vector<int>> res(ver.size());
    for (auto p : bridge) {
      int u = comp[p.first], v = comp[p.second];
      res[u].emplace_back(v);
      res[v].emplace_back(u);
    }
    return res;
  }
};

void cut(vector<vector<int>> &g, vector<vector<int>> &node, vector<int> &in,
         vector<bool> &used, vector<int> &p, int pos) {
  used[pos] = true;
  for (auto to : g[pos]) {
    if (used[to])
      continue;
    cut(g, node, in, used, p, to);
  }
  if (in[pos] == 1) {
    for (auto to : g[pos]) {
      in[to]--;
    }
    p.emplace_back(pos);
  }
}

int dfs(vector<vector<int>> &g, vector<int> &w, vector<bool> &used, int pos) {
  int res = w[pos];
  used[pos] = true;
  for (auto to : g[pos]) {
    if (used[to])
      continue;
    res += dfs(g, w, used, to);
  }
  return res;
}

int main() {
  int n, m;
  cin >> n >> m;

  vector<int> w(n);
  cin >> w;

  TwoEdgeConnectedComponent tecc(n);
  rep(i, m) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    tecc.addEdge(u, v);
  }
  tecc.solve();
  vector<vector<int>> g = tecc.getTree();
  vector<int> in(n);
  rep(i, n) in[i] = g[i].size();

  vector<int> p;
  vector<bool> used(n, 0);
  cut(g, tecc.ver, in, used, p, 0);

  vector<int> cg(g.size(), 0);
  int ans = accumulate(all(w), 0);
  show(ans) rep(i, p.size()) {
    cg[p[i]] = p[i];
    ans -= w[p[i]];
  }

  vector<vector<int>> ng(g.size());
  rep(i, g.size()) {
    for (auto j : g[i]) {
      if (cg[i] == 0 and cg[j] == 0)
        continue;
      ng[cg[i]].emplace_back(cg[j]);
      ng[cg[j]].emplace_back(cg[i]);
    }
  }

  used = vector<bool>(n, 0);
  used[0] = true;
  int maxi = 0;
  for (auto i : ng[0]) {
    maxi = max(maxi, dfs(ng, w, used, i));
  }
  cout << ans + maxi << endl;
}