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

// Template {{{
#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
using namespace std;
typedef long long LL;

#ifdef LOCAL
#include "contest.h"
#else
#define dump(x)
#endif

class range {
  struct Iterator {
    int val, inc;
    int operator*() { return val; }
    bool operator!=(Iterator &rhs) { return val < rhs.val; }
    void operator++() { val += inc; }
  };
  Iterator i, n;

public:
  range(int e) : i({0, 1}), n({e, 1}) {}
  range(int b, int e) : i({b, 1}), n({e, 1}) {}
  range(int b, int e, int inc) : i({b, inc}), n({e, inc}) {}
  Iterator &begin() { return i; }
  Iterator &end() { return n; }
};

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
inline bool valid(int x, int w) { return 0 <= x && x < w; }

void iostream_init() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.setf(ios::fixed);
  cout.precision(12);
}
//}}}

struct Edge {
  int dst;
  LL cost;
};
typedef vector<Edge> Node;
typedef vector<Node> Graph;
Graph G;
int N, M, S1, S2, T;
int MB;
const LL INF = 1e18;
vector<LL> calc_cost(int s, int t) {
  LL dist[1000][101] = {};
  typedef tuple<LL, int, int> TP;
  priority_queue<TP, vector<TP>, greater<TP>> que;
  REP(i, N) REP(j, MB + 1) dist[i][j] = INF;
  dist[s][0] = 0;
  que.push(TP(0, s, 0));
  while (!que.empty()) {
    LL d;
    int u, c;
    tie(d, u, c) = que.top();
    que.pop();
    for (Edge e : G[u]) {
      const int nu = e.dst;
      const int nc = c + (e.cost == -1 ? 1 : 0);
      const LL nd = d + (e.cost == -1 ? 0 : e.cost);
      if (nc <= MB && dist[nu][nc] > nd) {
        dist[nu][nc] = nd;
        que.push(TP(nd, nu, nc));
      }
    }
  }
  vector<LL> res(MB + 1);
  REP(i, MB + 1) res[i] = dist[t][i];
  return res;
}
// O(N)
LL get(vector<LL> cs, LL X) {
  LL res = cs[0];
  for (int i = 1; i < cs.size(); i++) {
    res = min(res, cs[i] + i * X);
  }
  return res;
}
// O(N)
LL calc_diff(vector<LL> cs1, vector<LL> cs2, LL X) {
  LL cost1 = get(cs1, X);
  LL cost2 = get(cs2, X);
  return abs(cost1 - cost2);
}
int main() {
  iostream_init();
  while (cin >> N >> M >> S1 >> S2 >> T && N > 0) {
    MB = 0;
    S1--;
    S2--;
    T--;
    G.assign(N, Node());
    REP(i, M) {
      int a, b;
      cin >> a >> b;
      string ws;
      cin >> ws;
      LL w;
      if (ws == "x") {
        w = -1;
        MB++;
      } else {
        w = stoll(ws);
      }
      a--;
      b--;
      G[a].push_back({b, w});
      G[b].push_back({a, w});
    }
    vector<LL> cs1 = calc_cost(S1, T);
    // REP(i, cs1.size()) cout << cs1[i] << " "; cout << endl;
    vector<LL> cs2 = calc_cost(S2, T);
    // REP(i, cs2.size()) cout << cs2[i] << " "; cout << endl;
    LL ans = calc_diff(cs1, cs2, 0);
    REP(i, cs1.size())
    REP(j, cs1.size()) if (i < j && cs1[i] < INF && cs1[j] < INF) {
      // cs[i] + i * X == cs[j] + j * X
      // cs[i] - cs[j] == (j-i) * X
      LL X = (cs1[i] - cs1[j]) / (j - i);
      // cout << "X: " << X << endl;
      for (LL dx = -1; dx <= 1; dx++) {
        if (X + dx >= 0)
          ans = min(ans, calc_diff(cs1, cs2, X + dx));
      }
    }
    REP(i, cs2.size())
    REP(j, cs2.size()) if (i < j && cs2[i] < INF && cs2[j] < INF) {
      // cs[i] + i * X == cs[j] + j * X
      // cs[i] - cs[j] == (j-i) * X
      LL X = (cs2[i] - cs2[j]) / (j - i);
      // cout << "X: " << X << endl;
      for (LL dx = -1; dx <= 1; dx++) {
        if (X + dx >= 0)
          ans = min(ans, calc_diff(cs1, cs2, X + dx));
      }
    }
    REP(i, cs2.size())
    REP(j, cs1.size()) if (i != j && cs2[i] < INF && cs1[j] < INF) {
      // cs[i] + i * X == cs[j] + j * X
      // cs[i] - cs[j] == (j-i) * X
      LL X = (cs2[i] - cs1[j]) / (j - i);
      // cout << "X: " << X << endl;
      for (LL dx = -1; dx <= 1; dx++) {
        if (X + dx >= 0)
          ans = min(ans, calc_diff(cs1, cs2, X + dx));
      }
    }
    cout << ans << endl;
  }
  return 0;
}

/* vim:set foldmethod=marker: */

Error: 0

Fixed submission:

// Template {{{
#include <bits/stdc++.h>
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
using namespace std;
typedef long long LL;

#ifdef LOCAL
#include "contest.h"
#else
#define dump(x)
#endif

class range {
  struct Iterator {
    int val, inc;
    int operator*() { return val; }
    bool operator!=(Iterator &rhs) { return val < rhs.val; }
    void operator++() { val += inc; }
  };
  Iterator i, n;

public:
  range(int e) : i({0, 1}), n({e, 1}) {}
  range(int b, int e) : i({b, 1}), n({e, 1}) {}
  range(int b, int e, int inc) : i({b, inc}), n({e, inc}) {}
  Iterator &begin() { return i; }
  Iterator &end() { return n; }
};

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
inline bool valid(int x, int w) { return 0 <= x && x < w; }

void iostream_init() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.setf(ios::fixed);
  cout.precision(12);
}
//}}}

struct Edge {
  int dst, cost;
};
typedef vector<Edge> Node;
typedef vector<Node> Graph;
Graph G;
int N, M, S1, S2, T;
int MB;
const LL INF = 1e18;
vector<LL> calc_cost(int s, int t) {
  LL dist[1000][101] = {};
  typedef tuple<LL, int, int> TP;
  priority_queue<TP, vector<TP>, greater<TP>> que;
  REP(i, N) REP(j, MB + 1) dist[i][j] = INF;
  dist[s][0] = 0;
  que.push(TP(0, s, 0));
  while (!que.empty()) {
    int d, u, c;
    tie(d, u, c) = que.top();
    que.pop();
    for (Edge e : G[u]) {
      const int nu = e.dst;
      const int nc = c + (e.cost == -1 ? 1 : 0);
      const LL nd = d + (e.cost == -1 ? 0 : e.cost);
      if (dist[nu][nc] > nd) {
        dist[nu][nc] = nd;
        que.push(TP(nd, nu, nc));
      }
    }
  }
  vector<LL> res(MB + 1);
  REP(i, MB + 1) res[i] = dist[t][i];
  return res;
}
// O(N)
LL get(vector<LL> cs, LL X) {
  LL res = cs[0];
  for (int i = 1; i < cs.size(); i++) {
    res = min(res, cs[i] + i * X);
  }
  return res;
}
// O(N)
LL calc_diff(vector<LL> cs1, vector<LL> cs2, LL X) {
  LL cost1 = get(cs1, X);
  LL cost2 = get(cs2, X);
  return abs(cost1 - cost2);
}
int main() {
  iostream_init();
  while (cin >> N >> M >> S1 >> S2 >> T && N > 0) {
    MB = 0;
    S1--;
    S2--;
    T--;
    G.resize(N);
    REP(i, M) {
      int a, b;
      cin >> a >> b;
      string ws;
      cin >> ws;
      int w;
      if (ws == "x") {
        w = -1;
        MB++;
      } else {
        w = stoi(ws);
      }
      a--;
      b--;
      G[a].push_back({b, w});
      G[b].push_back({a, w});
    }
    vector<LL> cs1 = calc_cost(S1, T);
    vector<LL> cs2 = calc_cost(S2, T);
    LL ans = calc_diff(cs1, cs2, 0);
    REP(i, cs1.size()) REP(j, cs1.size()) if (i < j) {
      // cs[i] + i * X == cs[j] + j * X
      // cs[i] - cs[j] == (j-i) * X
      LL X = (cs1[i] - cs1[j]) / (j - i);
      for (int dx = -1; dx <= 1; dx++) {
        ans = min(ans, calc_diff(cs1, cs2, X + dx));
      }
    }
    REP(i, cs2.size()) REP(j, cs2.size()) if (i < j) {
      // cs[i] + i * X == cs[j] + j * X
      // cs[i] - cs[j] == (j-i) * X
      LL X = (cs2[i] - cs2[j]) / (j - i);
      for (int dx = -1; dx <= 1; dx++) {
        ans = min(ans, calc_diff(cs1, cs2, X + dx));
      }
    }
    cout << ans << endl;
  }
  return 0;
}

/* vim:set foldmethod=marker: */