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

#include <iostream>
#include <limits>
#include <vector>

// -------------8<------- start of library -------8<------------------------
template <class T> struct Graph {
  const int n, s;
  const T INF;
  bool is_neg_cycle;
  std::vector<std::vector<std::pair<int, T>>> adj;
  std::vector<T> d;

  Graph(int _n, int _s)
      : n(_n), s(_s), INF(std::numeric_limits<T>::max()), is_neg_cycle(false),
        adj(n), d(n, INF) {}

  void add_edge(int u, int v, T w) {
    adj[u].emplace_back(std::make_pair(v, w));
  }
  T ShortestDistance(const int t) const { return d[t]; }
  bool IsNegativeCycleFromS() const { return is_neg_cycle; }

  bool CheckNegativeCycle() {
    std::fill(d.begin(), d.end(), 0);
    BellmanFord();
    return is_neg_cycle;
  }

  void BellmanFord() {
    d[s] = 0;
    for (int i = 0;; ++i) {
      bool update = false;
      for (int v = 0; v < n; ++v)
        for (const auto &e : adj[v])
          if (d[v] < INF && d[v] + e.second < d[e.first]) {
            d[e.first] = d[v] + e.second;
            update = true;
          }
      if (!update)
        break;
      if (i == n - 1) {
        is_neg_cycle = true;
        break;
      }
    }
  }
};
// -------------8<------- end of library ---------8-------------------------

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

  // AOJ GPL_1_B: Shortest Path - Single Shortest Path (Negative Edges)
  int n, m, r, s, t, d;
  std::cin >> n >> m >> r;

  Graph<int> g(n, r);
  for (int i = 0; i < m; ++i) {
    std::cin >> s >> t >> d;
    g.add_edge(s, t, d);
  }

  g.BellmanFord();
  if (g.IsNegativeCycleFromS())
    std::cout << "NEGATIVE CYCLE\\n";
  else {
    for (int v = 0; v < n; ++v) {
      int dist = g.ShortestDistance(v);
      if (dist == g.INF)
        std::cout << "INF\\n";
      else
        std::cout << dist << '\\n';
    }
  }

  return 0;
}


Error: -11

Fixed submission:

#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

typedef int Weight;
const Weight INF = 1e8;

struct Edge {
  int src, dst;
  Weight weight;
  Edge(int f, int t, Weight c) : src(f), dst(t), weight(c) {}
  bool operator<(const Edge &e);
};

bool Edge::operator<(const Edge &e) {
  return weight != e.weight ? weight > e.weight
         : src != e.src     ? src < e.src
                            : dst < e.dst;
}

typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

// グラフgの始点sから各頂点までの距離がdistに入る．
// 経路に負閉路が存在しないときtrue，そうでないときfalse．
// また，経路に負閉路を含む場合は，distが負の無限大となる．
// prefは最短路木の親頂点が入る
bool ShortestPath(const Graph &g, int s, vector<Weight> &dist,
                  vector<int> &prev) {
  int n = g.size();

  dist.assign(n, INF);
  dist[s] = 0;
  prev.assign(n, -2);

  bool negative_cycle = false;
  for (int k = 0; k < n; ++k) {
    for (int i = 0; i < n; ++i) {
      for (auto e = g[i].begin(); e != g[i].end(); ++e) {
        if (dist[e->src] != INF && dist[e->dst] > dist[e->src] + e->weight) {
          dist[e->dst] = dist[e->src] + e->weight;
          prev[e->dst] = e->src;
          if (k == n - 1) {
            dist[e->dst] = -INF;
            negative_cycle = true;
          }
        }
      }
    }
  }
  return !negative_cycle;
}

vector<int> BuildPath(const vector<int> &prev, int t) {
  vector<int> path;
  for (int u = t; u >= 0; u = prev[u])
    path.push_back(u);
  reverse(path.begin(), path.end());

  return path;
}

int main() {
  int V, E, r, s, t, d;

  cin >> V >> E >> r;
  Graph g;
  g.reserve(V);
  for (int i = 0; i < E; ++i) {
    cin >> s >> t >> d;
    g[s].push_back(Edge(s, t, d));
  }

  vector<Weight> dist;
  vector<int> prev;
  if (ShortestPath(g, r, dist, prev)) {
    for (int i = 0; i < V; ++i) {
      if (INF <= dist[i])
        cout << "INF\\n";
      else
        cout << dist[i] << '\\n';
    }
  } else {
    cout << "NEGATIVE CYCLE\\n";
  }

  return 0;
}