Problem p01653 (C++)

Buggy submission (status: Runtime Error):
#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

//// < "D:\D_Download\Visual Studio
///2015\Projects\programing_contest_c++\Debug\a.txt" > "D:\D_Download\Visual
///Studio 2015\Projects\programing_contest_c++\Debug\b.answer"

struct aa {
  int now;
  long long int time;
  int x;
};
class Compare {
public:
  // aa?????????????????¶
  bool operator()(const aa &l, const aa &r) { return l.time > r.time; }
};
template <class T> class cht {
public:
  vector<pair<T, T>> ls;
  bool check(const pair<T, T> &l1, const pair<T, T> &l2,
             const pair<T, T> &l3) const {
    return 1.l * (l2.first - l1.first) * (l3.second - l2.second) >=
           1.l * (l2.second - l1.second) * (l3.first - l2.first);
  }
  cht() : ls() {}
  cht(vector<pair<T, T>> &vs) : ls() {
    sort(vs.begin(), vs.end());
    for (auto v : vs) {
      add(v);
    }
  }
  void add(const pair<T, T> &p) {
    while (ls.size() >= 2) {
      if (!check(ls[ls.size() - 2], ls[ls.size() - 1], p)) {
        break;
      } else {
        ls.pop_back();
      }
    }
    if (ls.size() == 1 && ls.back().second == p.second) {
      ls.back().first = max(ls.back().first, p.first);
    } else {
      ls.emplace_back(p);
    }
  }
  T f(int k, const T &x) const { return ls[k].first * x + ls[k].second; }
  T query(const T &x) const {
    int amin = 0;
    int amax = ls.size();
    while (amin + 1 != amax) {
      int amid = (amin + amax) / 2;
      if (f(amid - 1, x) <= f(amid, x)) {
        amin = amid;
      } else {
        amax = amid;
      }
    }
    return f(amin, x);
  }
};
int main() {
  while (1) {
    int N, M, S1, S2, T;
    cin >> N >> M >> S1 >> S2 >> T;
    if (!N)
      break;
    S1--;
    S2--;
    T--;
    vector<vector<pair<int, long long int>>> edges(N);
    for (int i = 0; i < M; ++i) {
      int a, b;
      string w;
      cin >> a >> b >> w;
      a--;
      b--;
      long long int value;
      if (w == "x") {
        value = -1;
      } else {
        value = stoll(w);
      }
      edges[a].push_back(make_pair(b, value));
      edges[b].push_back(make_pair(a, value));
    }
    // if (N != 1000)continue;
    vector<vector<long long int>> memo(N, vector<long long int>(102, 1e18));
    memo[T][0] = 0;
    priority_queue<aa, vector<aa>, Compare> que;
    que.push(aa{T, 0, 0});
    while (!que.empty()) {
      aa atop(que.top());
      const int now = atop.now;
      const long long int now_time = atop.time;
      const int now_x = atop.x;
      que.pop();
      for (auto e : edges[atop.now]) {
        if (e.second == -1) {
          const long long int next_time = now_time;
          if (now_x >= 100)
            continue;
          if (memo[e.first][now_x + 1] > next_time) {
            bool ok = true;
            for (int ax = 0; ax < now_x + 1; ++ax) {
              if (memo[e.first][ax] <= next_time) {
                ok = false;
                break;
              }
            }
            if (!ok)
              continue;
            memo[e.first][now_x + 1] = next_time;

            que.push(aa{e.first, next_time, now_x + 1});
          }
        } else {
          const long long int next_time = now_time + e.second;
          if (memo[e.first][now_x] > next_time) {
            bool ok = true;
            for (int ax = 0; ax < now_x; ++ax) {
              if (memo[e.first][ax] <= next_time) {
                ok = false;
                break;
              }
            }
            if (!ok)
              continue;

            memo[e.first][now_x] = next_time;
            que.push(aa{e.first, next_time, now_x});
          }
        }
      }
    }

    cht<long long int> cht1, cht2;
    for (int i = 100; i >= 0; --i) {
      if (memo[S1][i] < 1e17) {
        cht1.add(make_pair(-i, -memo[S1][i]));
      }
      if (memo[S2][i] < 1e17) {
        cht2.add(make_pair(-i, -memo[S2][i]));
      }
    }
    vector<long long int> nums;
    nums.emplace_back(0);
    nums.emplace_back(static_cast<long long int>(1e15));
    assert(!cht1.ls.empty() && !cht2.ls.empty());
    for (int i = 0; i < int(cht1.ls.size()) - 1; ++i) {
      auto pa = cht1.ls[i];
      auto pb = cht1.ls[i + 1];
      assert(pb.first != pa.first);
      nums.emplace_back((pa.second - pb.second) / (pb.first - pa.first));
      nums.emplace_back((pa.second - pb.second) / (pb.first - pa.first) + 1);
    }
    for (int i = 0; i < int(cht2.ls.size()) - 1; ++i) {
      auto pa = cht2.ls[i];
      auto pb = cht2.ls[i + 1];
      assert(pb.first != pa.first);
      nums.emplace_back((pa.second - pb.second) / (pb.first - pa.first));
      nums.emplace_back((pa.second - pb.second) / (pb.first - pa.first) + 1);
    }
    sort(nums.begin(), nums.end());
    nums.erase(unique(nums.begin(), nums.end()), nums.end());
    long long int ans = 1e18;
    for (int i = 0; i < nums.size() - 1; ++i) {
      long long int al = nums[i];
      long long int ar = nums[i + 1];
      if (ar < 0)
        continue;
      else if (al < 0)
        al = 0;
      long long int lvalue1 = cht1.query(al);
      long long int lvalue2 = cht2.query(al);
      long long int rvalue1 = cht1.query(ar);
      long long int rvalue2 = cht2.query(ar);

      if ((lvalue1 > lvalue2 && rvalue1 > rvalue2) ||
          (lvalue1 < lvalue2 && rvalue1 < rvalue2)) {
        ans = min(ans, min(abs(lvalue1 - lvalue2), abs(rvalue1 - rvalue2)));
      } else {
        long long int dis1 = (rvalue1 - lvalue1) / (ar - al);
        long long int dis2 = (rvalue2 - lvalue2) / (ar - al);
        if (dis1 == dis2) {
          ans = min(ans, abs(lvalue1 - lvalue2));
        } else {
          long long int cx = abs((lvalue2 - lvalue1) / (dis1 - dis2));
          if (dis1 > dis2) {
            ans = min(ans, abs((lvalue2 - lvalue1) - (cx - 1) * (dis1 - dis2)));
            ans = min(ans, abs((lvalue2 - lvalue1) - (cx) * (dis1 - dis2)));
            ans = min(ans, abs((lvalue2 - lvalue1) - (cx + 1) * (dis1 - dis2)));
          } else {
            ans = min(ans, abs((lvalue2 - lvalue1) - (cx - 1) * (dis1 - dis2)));
            ans = min(ans, abs((lvalue2 - lvalue1) - (cx) * (dis1 - dis2)));
            ans = min(ans, abs((lvalue2 - lvalue1) - (cx + 1) * (dis1 - dis2)));
          }
        }
      }
    }

    cout << ans << endl;
  }
  return 0;
}

Fixed submission:
#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

//// < "D:\D_Download\Visual Studio
///2015\Projects\programing_contest_c++\Debug\a.txt" > "D:\D_Download\Visual
///Studio 2015\Projects\programing_contest_c++\Debug\b.answer"

struct aa {
  int now;
  long long int time;
  int x;
};
class Compare {
public:
  // aa?????????????????¶
  bool operator()(const aa &l, const aa &r) { return l.time > r.time; }
};
template <class T> class cht {
public:
  vector<pair<T, T>> ls;
  bool check(const pair<T, T> &l1, const pair<T, T> &l2,
             const pair<T, T> &l3) const {
    return 1.l * (l2.first - l1.first) * (l3.second - l2.second) >=
           1.l * (l2.second - l1.second) * (l3.first - l2.first);
  }
  cht() : ls() {}
  cht(vector<pair<T, T>> &vs) : ls() {
    sort(vs.begin(), vs.end());
    for (auto v : vs) {
      add(v);
    }
  }
  void add(const pair<T, T> &p) {
    while (ls.size() >= 2) {
      if (!check(ls[ls.size() - 2], ls[ls.size() - 1], p)) {
        break;
      } else {
        ls.pop_back();
      }
    }
    if (ls.size() == 1 && ls.back().second == p.second) {
      ls.back().first = max(ls.back().first, p.first);
    } else {
      ls.emplace_back(p);
    }
  }
  T f(int k, const T &x) const { return ls[k].first * x + ls[k].second; }
  T query(const T &x) const {
    int amin = 0;
    int amax = ls.size();
    while (amin + 1 != amax) {
      int amid = (amin + amax) / 2;
      if (f(amid - 1, x) <= f(amid, x)) {
        amin = amid;
      } else {
        amax = amid;
      }
    }
    return f(amin, x);
  }
};
int main() {
  while (1) {
    int N, M, S1, S2, T;
    cin >> N >> M >> S1 >> S2 >> T;
    if (!N)
      break;
    S1--;
    S2--;
    T--;
    vector<vector<pair<int, long long int>>> edges(N);
    for (int i = 0; i < M; ++i) {
      int a, b;
      string w;
      cin >> a >> b >> w;
      a--;
      b--;
      long long int value;
      if (w == "x") {
        value = -1;
      } else {
        value = stoll(w);
      }
      edges[a].push_back(make_pair(b, value));
      edges[b].push_back(make_pair(a, value));
    }
    // if (N != 1000)continue;
    vector<vector<long long int>> memo(N, vector<long long int>(102, 1e18));
    memo[T][0] = 0;
    priority_queue<aa, vector<aa>, Compare> que;
    que.push(aa{T, 0, 0});
    while (!que.empty()) {
      aa atop(que.top());
      const int now = atop.now;
      const long long int now_time = atop.time;
      const int now_x = atop.x;
      que.pop();
      for (auto e : edges[atop.now]) {
        if (e.second == -1) {
          const long long int next_time = now_time;
          if (now_x >= 100)
            continue;
          if (memo[e.first][now_x + 1] > next_time) {
            bool ok = true;
            for (int ax = 0; ax < now_x + 1; ++ax) {
              if (memo[e.first][ax] <= next_time) {
                ok = false;
                break;
              }
            }
            if (!ok)
              continue;
            memo[e.first][now_x + 1] = next_time;

            que.push(aa{e.first, next_time, now_x + 1});
          }
        } else {
          const long long int next_time = now_time + e.second;
          if (memo[e.first][now_x] > next_time) {
            bool ok = true;
            for (int ax = 0; ax < now_x; ++ax) {
              if (memo[e.first][ax] <= next_time) {
                ok = false;
                break;
              }
            }
            if (!ok)
              continue;

            memo[e.first][now_x] = next_time;
            que.push(aa{e.first, next_time, now_x});
          }
        }
      }
    }

    cht<long long int> cht1, cht2;
    for (int i = 100; i >= 0; --i) {
      if (memo[S1][i] < 1e17) {
        cht1.add(make_pair(-i, -memo[S1][i]));
      }
      if (memo[S2][i] < 1e17) {
        cht2.add(make_pair(-i, -memo[S2][i]));
      }
    }
    vector<long long int> nums;
    nums.emplace_back(0);
    nums.emplace_back(static_cast<long long int>(1e15));
    assert(!cht1.ls.empty() && !cht2.ls.empty());
    for (int i = 0; i < int(cht1.ls.size()) - 1; ++i) {
      auto pa = cht1.ls[i];
      auto pb = cht1.ls[i + 1];
      assert(pb.first != pa.first);
      nums.emplace_back((pa.second - pb.second) / (pb.first - pa.first));
      nums.emplace_back((pa.second - pb.second) / (pb.first - pa.first) + 1);
    }
    for (int i = 0; i < int(cht2.ls.size()) - 1; ++i) {
      auto pa = cht2.ls[i];
      auto pb = cht2.ls[i + 1];
      assert(pb.first != pa.first);
      nums.emplace_back((pa.second - pb.second) / (pb.first - pa.first));
      nums.emplace_back((pa.second - pb.second) / (pb.first - pa.first) + 1);
    }
    sort(nums.begin(), nums.end());
    nums.erase(unique(nums.begin(), nums.end()), nums.end());
    long long int ans = 1e18;
    for (int i = 0; i < nums.size() - 1; ++i) {
      long long int al = nums[i];
      long long int ar = nums[i + 1];
      if (ar < 0)
        continue;
      else if (al < 0)
        al = 0;
      if (al == ar)
        continue;
      long long int lvalue1 = cht1.query(al);
      long long int lvalue2 = cht2.query(al);
      long long int rvalue1 = cht1.query(ar);
      long long int rvalue2 = cht2.query(ar);

      if ((lvalue1 > lvalue2 && rvalue1 > rvalue2) ||
          (lvalue1 < lvalue2 && rvalue1 < rvalue2)) {
        ans = min(ans, min(abs(lvalue1 - lvalue2), abs(rvalue1 - rvalue2)));
      } else {
        long long int dis1 = (rvalue1 - lvalue1) / (ar - al);
        long long int dis2 = (rvalue2 - lvalue2) / (ar - al);
        if (dis1 == dis2) {
          ans = min(ans, abs(lvalue1 - lvalue2));
        } else {
          long long int cx = abs((lvalue2 - lvalue1) / (dis1 - dis2));
          if (dis1 > dis2) {
            ans = min(ans, abs((lvalue2 - lvalue1) - (cx - 1) * (dis1 - dis2)));
            ans = min(ans, abs((lvalue2 - lvalue1) - (cx) * (dis1 - dis2)));
            ans = min(ans, abs((lvalue2 - lvalue1) - (cx + 1) * (dis1 - dis2)));
          } else {
            ans = min(ans, abs((lvalue2 - lvalue1) - (cx - 1) * (dis1 - dis2)));
            ans = min(ans, abs((lvalue2 - lvalue1) - (cx) * (dis1 - dis2)));
            ans = min(ans, abs((lvalue2 - lvalue1) - (cx + 1) * (dis1 - dis2)));
          }
        }
      }
    }

    cout << ans << endl;
  }
  return 0;
}