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

// ?????????????????????

#include <bits/stdc++.h>

using namespace std;

struct Bipartite_Matching {
  vector<vector<int>> graph;
  vector<int> match, alive, used;
  int timestamp;

  Bipartite_Matching(int n) {
    timestamp = 0;
    graph.resize(n);
    alive.assign(n, 0);
    used.assign(n, 0);
    match.assign(n, -1);
  }

  void add_edge(int u, int v) {
    graph[u].push_back(v);
    graph[v].push_back(u);
  }

  bool dfs(int v) {
    used[v] = timestamp;
    for (int i = 0; i < graph[v].size(); i++) {
      int u = graph[v][i], w = match[u];
      if (alive[u] == 0)
        continue;
      if (w == -1 || (used[w] != timestamp && dfs(w))) {
        match[v] = u;
        match[u] = v;
        return (true);
      }
    }
    return (false);
  }

  int bipartite_matching() {
    int ret = 0;
    for (int i = 0; i < graph.size(); i++) {
      if (alive[i] == 0)
        continue;
      if (match[i] == -1) {
        ++timestamp;
        ret += dfs(i);
      }
    }
    return (ret);
  }

  int add(int k) {
    alive[k] = 1;
    ++timestamp;
    return (dfs(k));
  }
};

int main() {
  int N, A[150000], idx[150000];
  vector<int> g[150000];
  bool dep[150000] = {};

  cin >> N;
  ++N;
  for (int i = 1; i < N; i++) {
    cin >> idx[i];
    g[idx[i]].push_back(i);
    dep[i] = dep[idx[i]] ^ 1;
  }

  Bipartite_Matching flow(N);
  vector<int> left, right;
  for (int i = 0; i < N; i++) {
    if (dep[i])
      left.push_back(i);
    else
      right.push_back(i);
  }

  for (int i = 1; i < N; i++) {
    int oi, beet;
    if (dep[i])
      oi = lower_bound(begin(left), end(left), i) - begin(left);
    else
      oi = (int)(lower_bound(begin(right), end(right), i) - begin(right)) +
           left.size();

    if (dep[idx[i]])
      beet = lower_bound(begin(left), end(left), idx[i]) - begin(left);
    else
      beet =
          (int)(lower_bound(begin(right), end(right), idx[i]) - begin(right)) +
          left.size();

    flow.add_edge(oi, beet);
  }
  flow.alive[(int)(lower_bound(begin(right), end(right), 0) - begin(right)) +
             left.size()] = true;

  flow.bipartite_matching();
  int ret = 0;
  for (int i = 1; i < N; i++) {
    int oi;
    if (dep[i])
      oi = lower_bound(begin(left), end(left), i) - begin(left);
    else
      oi = (int)(lower_bound(begin(right), end(right), i) - begin(right)) +
           left.size();
    ret += flow.add(oi);
    cout << ret << endl;
  }
}

Error: 0

Fixed submission:

// ?????????????????????

#include <bits/stdc++.h>

using namespace std;

struct Bipartite_Matching {
  vector<vector<int>> graph;
  vector<int> match, alive, used;
  int timestamp;

  Bipartite_Matching(int n) {
    timestamp = 0;
    graph.resize(n);
    alive.assign(n, 0);
    used.assign(n, 0);
    match.assign(n, -1);
  }

  void add_edge(int u, int v) {
    graph[u].push_back(v);
    graph[v].push_back(u);
  }

  bool dfs(int v) {
    used[v] = timestamp;
    for (int i = 0; i < graph[v].size(); i++) {
      int u = graph[v][i], w = match[u];
      if (alive[u] == 0)
        continue;
      if (w == -1 || (used[w] != timestamp && dfs(w))) {
        match[v] = u;
        match[u] = v;
        return (true);
      }
    }
    return (false);
  }

  int bipartite_matching() {
    int ret = 0;
    for (int i = 0; i < graph.size(); i++) {
      if (alive[i] == 0)
        continue;
      if (match[i] == -1) {
        ++timestamp;
        ret += dfs(i);
      }
    }
    return (ret);
  }

  int add(int k) {
    alive[k] = 1;
    ++timestamp;
    return (dfs(k));
  }
};

int main() {
  int N, A[100000], idx[5000];
  vector<int> g[5000];
  bool dep[5000] = {};

  cin >> N;
  ++N;
  for (int i = 1; i < N; i++) {
    cin >> idx[i];
    g[idx[i]].push_back(i);
    dep[i] = dep[idx[i]] ^ 1;
  }

  Bipartite_Matching flow(N);
  vector<int> left, right;
  for (int i = 0; i < N; i++) {
    if (dep[i])
      left.push_back(i);
    else
      right.push_back(i);
  }

  for (int i = 1; i < N; i++) {
    int oi, beet;
    if (dep[i])
      oi = lower_bound(begin(left), end(left), i) - begin(left);
    else
      oi = (int)(lower_bound(begin(right), end(right), i) - begin(right)) +
           left.size();

    if (dep[idx[i]])
      beet = lower_bound(begin(left), end(left), idx[i]) - begin(left);
    else
      beet =
          (int)(lower_bound(begin(right), end(right), idx[i]) - begin(right)) +
          left.size();

    flow.add_edge(oi, beet);
  }
  flow.alive[(int)(lower_bound(begin(right), end(right), 0) - begin(right)) +
             left.size()] = true;

  flow.bipartite_matching();
  int ret = 0;
  for (int i = 1; i < N; i++) {
    int oi;
    if (dep[i])
      oi = lower_bound(begin(left), end(left), i) - begin(left);
    else
      oi = (int)(lower_bound(begin(right), end(right), i) - begin(right)) +
           left.size();
    ret += flow.add(oi);
    cout << ret << endl;
  }
}