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

#include <algorithm>
#include <cassert>
#include <climits>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;

typedef pair<int, int> pi;
typedef pair<pair<int, int>, int> ppi;
typedef vector<pair<pair<int, int>, int>> vppi;
#define ff first.first
#define fs first.second
#define se second

struct Stone {
  int row, col, d;
};

const int VMAX = 1600;
const int MMAX = 80;
const int S = 1598;
const int T = 1599;

struct Edge {
  int to1, to2, cost;
};
vector<Edge> G[VMAX][MMAX];
int dist[VMAX][MMAX];

void addEdge(int u1, int u2, int v1, int v2, int cost) {
  G[u1][u2].push_back((Edge){v1, v2, cost});
}

int risk(Stone a, Stone b) { return (a.d + b.d) * abs(a.col - b.col); }

int main() {
  int n, m;
  while (cin >> n >> m, n) {
    for (int i = 0; i < VMAX; ++i) {
      for (int j = 0; j < MMAX; ++j) {
        G[i][j].clear();
      }
    }

    vector<Stone> stones;
    int k;
    for (int i = 0; i < n; ++i) {
      cin >> k;
      int x, d;
      for (int j = 0; j < k; ++j) {
        cin >> x >> d;
        stones.push_back((Stone){i, x, d});
      }
    }

    for (int i = 0; i < (int)stones.size(); ++i) {
      // S
      if (stones[i].row == 0) {
        for (int j = 0; j <= m; ++j) {
          addEdge(S, j, i, j, 0);
        }
      } else if (stones[i].row == 1) {
        for (int j = 1; j <= m; ++j) {
          addEdge(S, j, i, j - 1, 0);
        }
      }

      // T
      if (stones[i].row == n - 1) {
        for (int j = 0; j <= m; ++j) {
          addEdge(i, j, T, j, 0);
        }
      } else if (stones[i].row == n - 2) {
        for (int j = 1; j <= m; ++j) {
          addEdge(i, j, T, j - 1, 0);
        }
      }

      // other
      for (int j = i + 1; j < (int)stones.size(); ++j) {
        int jump = stones[j].row - stones[i].row;
        if (3 <= jump)
          break;
        if (jump == 1) {
          for (int k = 0; k <= m; ++k) {
            addEdge(i, k, j, k, risk(stones[i], stones[j]));
          }
        } else if (jump == 2) {
          for (int k = 1; k <= m; ++k) {
            addEdge(i, k, j, k - 1, risk(stones[i], stones[j]));
          }
        }
      }
    }

    for (int i = 0; i < VMAX; ++i) {
      for (int j = 0; j < MMAX; ++j) {
        dist[i][j] = INT_MAX;
      }
    }
    dist[S][m] = 0;
    priority_queue<ppi, vppi, greater<ppi>> q;
    q.push(make_pair(make_pair(0, S), m));
    while (!q.empty()) {
      int cost = q.top().ff;
      int u1 = q.top().fs;
      int u2 = q.top().se;
      q.pop();
      for (int i = 0; i < (int)G[u1][u2].size(); ++i) {
        Edge &e = G[u1][u2][i];
        if (cost + e.cost < dist[e.to1][e.to2]) {
          dist[e.to1][e.to2] = cost + e.cost;
          q.push(make_pair(make_pair(cost + e.cost, e.to1), e.to2));
        }
      }
    }
    cout << *min_element(dist[T], dist[T] + MMAX) << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <climits>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;

typedef pair<int, int> pi;
typedef pair<pair<int, int>, int> ppi;
typedef vector<pair<pair<int, int>, int>> vppi;
#define ff first.first
#define fs first.second
#define se second

struct Stone {
  int row, col, d;
};

const int S = 150;
const int T = 151;

struct Edge {
  int to1, to2, cost;
};
vector<Edge> G[160][80];
int dist[160][80];

void addEdge(int u1, int u2, int v1, int v2, int cost) {
  G[u1][u2].push_back((Edge){v1, v2, cost});
}

int risk(Stone a, Stone b) { return (a.d + b.d) * abs(a.col - b.col); }

int main() {
  int n, m;
  while (cin >> n >> m, n) {
    for (int i = 0; i < 160; ++i) {
      for (int j = 0; j < 80; ++j) {
        G[i][j].clear();
      }
    }

    vector<Stone> stones;
    int k;
    for (int i = 0; i < n; ++i) {
      cin >> k;
      int x, d;
      for (int j = 0; j < k; ++j) {
        cin >> x >> d;
        stones.push_back((Stone){i, x, d});
      }
    }

    for (int i = 0; i < (int)stones.size(); ++i) {
      // S
      if (stones[i].row == 0) {
        for (int j = 0; j < 80; ++j) {
          addEdge(S, j, i, j, 0);
        }
      } else if (stones[i].row == 1) {
        for (int j = 1; j < 80; ++j) {
          addEdge(S, j, i, j - 1, 0);
        }
      }

      // T
      if (stones[i].row == n - 1) {
        for (int j = 0; j < 80; ++j) {
          addEdge(i, j, T, j, 0);
        }
      } else if (stones[i].row == n - 2) {
        for (int j = 1; j < 80; ++j) {
          addEdge(i, j, T, j - 1, 0);
        }
      }

      // other
      for (int j = i + 1; j < (int)stones.size(); ++j) {
        int jump = stones[j].row - stones[i].row;
        if (3 <= jump)
          break;
        if (jump == 1) {
          for (int k = 0; k < 80; ++k) {
            addEdge(i, k, j, k, risk(stones[i], stones[j]));
          }
        } else if (jump == 2) {
          for (int k = 1; k < 80; ++k) {
            addEdge(i, k, j, k - 1, risk(stones[i], stones[j]));
          }
        }
      }
    }

    for (int i = 0; i < 160; ++i) {
      for (int j = 0; j < 80; ++j) {
        dist[i][j] = INT_MAX;
      }
    }
    dist[S][m] = 0;
    priority_queue<ppi, vppi, greater<ppi>> q;
    q.push(make_pair(make_pair(0, S), m));
    while (!q.empty()) {
      int cost = q.top().ff;
      int u1 = q.top().fs;
      int u2 = q.top().se;
      q.pop();
      for (int i = 0; i < (int)G[u1][u2].size(); ++i) {
        Edge &e = G[u1][u2][i];
        if (cost + e.cost < dist[e.to1][e.to2]) {
          dist[e.to1][e.to2] = cost + e.cost;
          q.push(make_pair(make_pair(cost + e.cost, e.to1), e.to2));
        }
      }
    }
    cout << *min_element(dist[T], dist[T] + 80) << endl;
  }
  return 0;
}