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

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <utility>
#include <vector>
using namespace std;

int N, to[100010], dist[100010];
typedef pair<int, int> pii;
const int INF = 1 << 25;

struct UnionFind {
  int node[100010], edge_cnt[100010];
  UnionFind() {
    memset(node, -1, sizeof(node));
    memset(edge_cnt, 0, sizeof(edge_cnt));
  }
  int find(int x) { return node[x] < 0 ? x : node[x] = find(node[x]); }
  int size(int x) { return -node[find(x)]; }
  void unite(int x, int y) {
    x = find(x), y = find(y);
    if (size(x) > size(y))
      swap(x, y);
    edge_cnt[y]++;
    if (x == y)
      return;

    // x を y に統合
    node[y] += node[x];
    node[x] = y;
    edge_cnt[y] += edge_cnt[x];
  }
  int edge(int x) { return edge_cnt[find(x)]; }
};

UnionFind uf;
int main() {
  scanf("%d", &N);
  for (int i = 0; i < N; i++) {
    scanf("%d", &to[i]);
    if (to[i] != 0)
      uf.unite(i, i + to[i]);
  }
  for (int i = 0; i < N; i++) {
    dist[i] = INF;
    if (uf.size(i) <= uf.edge(i)) {
      to[i] = INF;
    }
    // printf("operate: %d, size = %d\\n", to[i], uf.size(i));
  }

  dist[0] = 0;
  priority_queue<pii, vector<pii>, greater<pii>> que;
  que.push(make_pair(0, 0));

  while (que.size()) {
    pii cur = que.top();
    que.pop();
    int pos = cur.second, cost = cur.first;

    if (pos == N - 1) {
      printf("%d\\n", dist[pos]);
      return 0;
    }

    if (to[pos] == 0) {
      for (int k = 1; k <= 6; k++) {
        int npos = min(pos + k, N - 1);
        if (to[npos] == INF)
          continue;
        if (dist[npos] > dist[pos] + 1) {
          dist[npos] = dist[pos] + 1;
          que.push(make_pair(dist[npos], npos));
        }
      }
    } else {
      int npos = to[pos] + pos;
      if (dist[npos] > dist[pos]) {
        dist[npos] = dist[pos];
        que.push(make_pair(dist[npos], npos));
      }
    }
  }
  return 0;
}


Error: 0

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <queue>
#include <set>
#include <utility>
#include <vector>
using namespace std;

int N, to[100010], dist[100010];
const int INF = 1 << 25;
set<int> used;
typedef pair<int, int> pii;

void src(int cur, set<int> vec) {
  if (used.count(cur))
    return;
  vec.insert(cur);
  if (to[cur] == 0) {
    int S = vec.size();
    for (auto x : vec) {
      used.insert(x);
      int diff = cur - x;
      to[x] = diff;
    }
  } else {
    if (!vec.count(cur + to[cur])) {
      src(cur + to[cur], vec);
    } else {
      for (auto x : vec) {
        to[x] = INF;
        used.insert(x);
      }
    }
  }
}

int main() {
  scanf("%d", &N);
  for (int i = 0; i < N; i++) {
    scanf("%d", &to[i]);
  }

  for (int i = 0; i < N; i++) {
    src(i, set<int>());
    dist[i] = INF;
  }

  dist[0] = 0;
  // cost, pos
  priority_queue<pii, vector<pii>, greater<pii>> que;
  que.push(make_pair(0, 0));

  while (que.size()) {
    pii cur = que.top();
    que.pop();
    int cost = cur.first, pos = cur.second;

    if (to[pos] == 0) {
      for (int i = 1; i <= 6; i++) {
        int npos = min(pos + i, N - 1);
        if (to[npos] == INF)
          continue;
        if (dist[npos] > dist[pos] + 1) {
          dist[npos] = dist[pos] + 1;
          que.push(make_pair(dist[npos], npos));
        }
      }
    } else {
      int npos = pos + to[pos];
      if (dist[npos] > dist[pos]) {
        dist[npos] = dist[pos];
        que.push(make_pair(dist[npos], npos));
      }
    }
  }

  printf("%d\\n", dist[N - 1]);
  return 0;
}