Problem p03645 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long double ld;
#define ALL(x) (x).begin(), (x).end() // sortなどの引数を省略したい
#define SIZE(x) ((ll)(x).size())      // sizeをsize_tからllに直しておく
#define INF 1000000000000             // 10^12
#define MOD 10000007                  // 10^9+7

template <typename T> string printVector(const vector<T> &data) {
  stringstream ss;
  ostream_iterator<T> out_it(ss, ", ");
  ss << "[";
  std::copy(data.begin(), data.end() - 1, out_it);
  ss << data.back() << "]";
  return ss.str();
}

class UnionFind {
public:
  vector<ll> par; // 各元の親を表す配列
  vector<ll> siz; // 素集合のサイズを表す配列(1 で初期化)

  // Constructor
  UnionFind(ll sz_) : par(sz_), siz(sz_, 1LL) {
    for (ll i = 0; i < sz_; ++i)
      par[i] = i; // 初期では親は自分自身
  }

  void init(ll sz_) {
    par.resize(sz_);
    siz.assign(sz_, 1LL); // resize だとなぜか初期化されなかった
    for (ll i = 0; i < sz_; ++i)
      par[i] = i; // 初期では親は自分自身
  }

  // Member Function
  // Find
  ll root(ll x) { // 根の検索
    while (par[x] != x) {
      x = par[x] = par[par[x]]; // x の親の親を x の親とする
    }
    return x;
  }

  // Union(Unite, Merge)
  bool merge(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    // merge technique（データ構造をマージするテク．小を大にくっつける）
    if (siz[x] < siz[y])
      swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(ll x, ll y) { // 連結判定
    return root(x) == root(y);
  }

  ll size(ll x) { // 素集合のサイズ
    return siz[root(x)];
  }
};

#define MAX_V 100001

struct edge {
  int to;
  int cost;
};

// <最短距離, 頂点の番号>
using P = pair<ll, int>;

int V;
vector<edge> graph[MAX_V];
ll d[MAX_V];

void dijkstra(int s) {
  priority_queue<P, vector<P>, greater<P>> que;
  fill(d, d + V, INF);
  d[s] = 0;
  que.push(P(0, s));

  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second;
    if (d[v] < p.first)
      continue;

    for (int i = 0; i < graph[v].size(); ++i) {
      edge e = graph[v][i];
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        que.push(P(d[e.to], e.to));
      }
    }
  }
}

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

  int n, m;
  cin >> n >> m;
  V = n;

  for (int i = 0; i < m; ++i) {
    int a, b;
    cin >> a >> b;
    graph[a - 1].push_back(edge{b - 1, 1});
    graph[b - 1].push_back(edge{a - 1, 1});
  }
  dijkstra(0);
  if (d[n - 1] == 2) {
    cout << "POSSIBLE" << endl;
  } else {
    cout << "IMPOSSIBLE" << endl;
  }
}


Fixed submission:
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef long double ld;
#define ALL(x) (x).begin(), (x).end() // sortなどの引数を省略したい
#define SIZE(x) ((ll)(x).size())      // sizeをsize_tからllに直しておく
#define INF 1000000000000             // 10^12
#define MOD 10000007                  // 10^9+7

template <typename T> string printVector(const vector<T> &data) {
  stringstream ss;
  ostream_iterator<T> out_it(ss, ", ");
  ss << "[";
  std::copy(data.begin(), data.end() - 1, out_it);
  ss << data.back() << "]";
  return ss.str();
}

class UnionFind {
public:
  vector<ll> par; // 各元の親を表す配列
  vector<ll> siz; // 素集合のサイズを表す配列(1 で初期化)

  // Constructor
  UnionFind(ll sz_) : par(sz_), siz(sz_, 1LL) {
    for (ll i = 0; i < sz_; ++i)
      par[i] = i; // 初期では親は自分自身
  }

  void init(ll sz_) {
    par.resize(sz_);
    siz.assign(sz_, 1LL); // resize だとなぜか初期化されなかった
    for (ll i = 0; i < sz_; ++i)
      par[i] = i; // 初期では親は自分自身
  }

  // Member Function
  // Find
  ll root(ll x) { // 根の検索
    while (par[x] != x) {
      x = par[x] = par[par[x]]; // x の親の親を x の親とする
    }
    return x;
  }

  // Union(Unite, Merge)
  bool merge(ll x, ll y) {
    x = root(x);
    y = root(y);
    if (x == y)
      return false;
    // merge technique（データ構造をマージするテク．小を大にくっつける）
    if (siz[x] < siz[y])
      swap(x, y);
    siz[x] += siz[y];
    par[y] = x;
    return true;
  }

  bool issame(ll x, ll y) { // 連結判定
    return root(x) == root(y);
  }

  ll size(ll x) { // 素集合のサイズ
    return siz[root(x)];
  }
};

#define MAX_V 200005

struct edge {
  int to;
  int cost;
};

// <最短距離, 頂点の番号>
using P = pair<ll, int>;

int V;
vector<edge> graph[MAX_V];
ll d[MAX_V];

void dijkstra(int s) {
  priority_queue<P, vector<P>, greater<P>> que;
  fill(d, d + V, INF);
  d[s] = 0;
  que.push(P(0, s));

  while (!que.empty()) {
    P p = que.top();
    que.pop();
    int v = p.second;
    if (d[v] < p.first)
      continue;

    for (int i = 0; i < graph[v].size(); ++i) {
      edge e = graph[v][i];
      if (d[e.to] > d[v] + e.cost) {
        d[e.to] = d[v] + e.cost;
        que.push(P(d[e.to], e.to));
      }
    }
  }
}

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

  int n, m;
  cin >> n >> m;
  V = n;

  for (int i = 0; i < m; ++i) {
    int a, b;
    cin >> a >> b;
    graph[a - 1].push_back(edge{b - 1, 1});
    graph[b - 1].push_back(edge{a - 1, 1});
  }
  dijkstra(0);
  if (d[n - 1] == 2) {
    cout << "POSSIBLE" << endl;
  } else {
    cout << "IMPOSSIBLE" << endl;
  }
}