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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>

using namespace std;

#define dump(n) cout << "# " << #n << '=' << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define iter(c) __typeof__((c).begin())
#define foreach(i, c) for (iter(c) i = (c).begin(); i != (c).end(); ++i)
#define all(c) (c).begin(), (c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int INFTY = 1 << 29;
const double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

const double PI = acos(-1);

struct Point {
  double x, y;
  Point() {}
  Point(double x, double y) : x(x), y(y) {}
};
struct Line {
  Point pos, dir;
  Line() {}
  Line(Point p, Point d) : pos(p), dir(d) {}
  Line(double px, double py, double dx, double dy) : pos(px, py), dir(dx, dy) {}
};
typedef Line Segment;

bool operator==(Point a, Point b) {
  return abs(a.x - b.x) < EPS && abs(a.y - b.y) < EPS;
}
bool operator!=(Point a, Point b) { return !(a == b); }
Point operator+(Point a, Point b) { return Point(a.x + b.x, a.y + b.y); }
Point operator-(Point a, Point b) { return Point(a.x - b.x, a.y - b.y); }
Point operator*(double c, Point p) { return Point(c * p.x, c * p.y); }
Point operator/(Point p, double c) { return Point(p.x / c, p.y / c); }
struct LessX {
  bool operator()(Point a, Point b) {
    return abs(a.x - b.x) > EPS ? a.x < b.x - EPS : a.y < b.y - EPS;
  }
};

int Signum(double x) { return x < -EPS ? -1 : x < EPS ? 0 : 1; }
double Abs(Point p) { return sqrt(p.x * p.x + p.y * p.y); }
double Abs2(Point p) { return p.x * p.x + p.y * p.y; }
double Arg(Point p) { return atan2(p.y, p.x); }
double Dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }
double Cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }
int CCW(Point a, Point b, Point c) {
  Point d1 = b - a, d2 = c - a;
  if (int sign = Signum(Cross(d1, d2)))
    return sign; // 1:ccw,-1:cw
  if (Dot(d1, d2) < -EPS)
    return -2; // c-a-b
  if (Abs2(d1) < Abs2(d2) - EPS)
    return 2; // a-b-c
  return 0;   // a-c-b
}

bool IntersectSP(Segment s, Point p) {
  return CCW(s.pos, s.pos + s.dir, p) == 0;
}
bool IntersectSS(Segment a, Segment b) {
  int c1 = CCW(a.pos, a.pos + a.dir, b.pos),
      c2 = CCW(a.pos, a.pos + a.dir, b.pos + b.dir);
  int c3 = CCW(b.pos, b.pos + b.dir, a.pos),
      c4 = CCW(b.pos, b.pos + b.dir, a.pos + a.dir);
  return c1 * c2 <= 0 && c3 * c4 <= 0;
}
Point InterPointLL(Line a, Line b) {
  if (abs(Cross(a.dir, b.dir)) < EPS)
    return a.pos;
  return a.pos + Cross(b.pos - a.pos, b.dir) / Cross(a.dir, b.dir) * a.dir;
}
Point InterPointSS(Segment a, Segment b) {
  if (abs(Cross(a.dir, b.dir)) < EPS) {
    if (IntersectSP(b, a.pos))
      return a.pos;
    if (IntersectSP(b, a.pos + a.dir))
      return a.pos + a.dir;
    if (IntersectSP(a, b.pos))
      return b.pos;
    if (IntersectSP(a, b.pos + b.dir))
      return b.pos + b.dir;
  }
  return InterPointLL(a, b);
}

struct Edge {
  int src, dst;
  double weight;
  Edge() {}
  Edge(int s, int d, double w) : src(s), dst(d), weight(w) {}
  bool operator<(const Edge &e) const { return Signum(weight - e.weight) < 0; }
  bool operator>(const Edge &e) const { return Signum(weight - e.weight) > 0; }
};
typedef vector<vector<Edge>> Graph;

void SegmentArrangement(const vector<Segment> &ss, Graph &g,
                        vector<Point> &ps) {
  rep(i, ss.size()) {
    ps.push_back(ss[i].pos);
    ps.push_back(ss[i].pos + ss[i].dir);
    repi(j, i + 1, ss.size()) if (IntersectSS(ss[i], ss[j]))
        ps.push_back(InterPointSS(ss[i], ss[j]));
  }
  sort(all(ps), LessX());
  ps.erase(unique(all(ps)), ps.end());

  g.resize(ps.size());
  rep(i, ss.size()) {
    vector<pair<double, int>> ds;
    rep(j, ps.size()) if (IntersectSP(ss[i], ps[j]))
        ds.push_back(mp(Abs(ps[j] - ss[i].pos), j));
    sort(all(ds));
    rep(j, ds.size() - 1) {
      int u = ds[j].second, v = ds[j + 1].second;
      double w = ds[j + 1].first - ds[j].first;
      g[u].push_back(Edge(u, v, w));
      g[v].push_back(Edge(v, u, w));
    }
  }
}

int main() {
  for (int n; cin >> n, n;) {
    vector<Segment> ss(n);
    rep(i, n) {
      int x1, y1, x2, y2;
      cin >> x1 >> y1 >> x2 >> y2;
      ss[i] = Segment(x1, y1, x2 - x1, y2 - y1);
    }
    Point st, go;
    cin >> st.x >> st.y >> go.x >> go.y;

    Graph g;
    vector<Point> ps;
    SegmentArrangement(ss, g, ps);

    vi sum(g.size());
    repi(i, 1, g.size()) sum[i] = sum[i - 1] + g[i - 1].size();

    Graph g2(sum.back() + g.back().size());
    rep(i, g.size()) rep(j, g[i].size()) rep(k, g[g[i][j].dst].size()) {
      Edge e1 = g[i][j], e2 = g[g[i][j].dst][k];
      int u = sum[e1.src] + j, v = sum[e2.src] + k;
      double w =
          abs(Arg(ps[e1.dst] - ps[e1.src]) - Arg(ps[e2.dst] - ps[e2.src])) *
          180 / PI;
      w = min(w, 360 - w);
      g2[u].emplace_back(u, v, w);
    }

    vi sts, gos;
    rep(i, g.size()) rep(j, g[i].size()) {
      Segment seg(ps[i], ps[g[i][j].dst] - ps[i]);
      if (IntersectSP(seg, st))
        sts.push_back(sum[i] + j);
      if (IntersectSP(seg, go))
        gos.push_back(sum[i] + j);
    }

    vd ws(g2.size(), INFTY);
    priority_queue<Edge, vector<Edge>, greater<Edge>> pq;
    rep(i, sts.size()) pq.emplace(-1, sts[i], 0);
    while (!pq.empty()) {
      Edge cur = pq.top();
      pq.pop();
      if (ws[cur.dst] != INFTY)
        continue;
      ws[cur.dst] = cur.weight;
      for (Edge e : g2[cur.dst])
        pq.emplace(e.src, e.dst, cur.weight + e.weight);
    }
    double res = INFTY;
    rep(i, gos.size()) res = min(res, ws[gos[i]]);

    if (res == INFTY)
      puts("-1");
    else
      printf("%f\\n", res);
  }

  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>

using namespace std;

#define dump(n) cout << "# " << #n << '=' << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define iter(c) __typeof__((c).begin())
#define foreach(i, c) for (iter(c) i = (c).begin(); i != (c).end(); ++i)
#define all(c) (c).begin(), (c).end()
#define mp make_pair

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;
typedef pair<int, int> pii;

const int INFTY = 1 << 29;
const double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

const double PI = acos(-1);

struct Point {
  double x, y;
  Point() {}
  Point(double x, double y) : x(x), y(y) {}
};
struct Line {
  Point pos, dir;
  Line() {}
  Line(Point p, Point d) : pos(p), dir(d) {}
  Line(double px, double py, double dx, double dy) : pos(px, py), dir(dx, dy) {}
};
typedef Line Segment;

bool operator==(Point a, Point b) {
  return abs(a.x - b.x) < EPS && abs(a.y - b.y) < EPS;
}
bool operator!=(Point a, Point b) { return !(a == b); }
Point operator+(Point a, Point b) { return Point(a.x + b.x, a.y + b.y); }
Point operator-(Point a, Point b) { return Point(a.x - b.x, a.y - b.y); }
Point operator*(double c, Point p) { return Point(c * p.x, c * p.y); }
Point operator/(Point p, double c) { return Point(p.x / c, p.y / c); }
struct LessX {
  bool operator()(Point a, Point b) {
    return abs(a.x - b.x) > EPS ? a.x < b.x - EPS : a.y < b.x - EPS;
  }
};

int Signum(double x) { return x < -EPS ? -1 : x < EPS ? 0 : 1; }
double Abs(Point p) { return sqrt(p.x * p.x + p.y * p.y); }
double Abs2(Point p) { return p.x * p.x + p.y * p.y; }
double Arg(Point p) { return atan2(p.y, p.x); }
double Dot(Point a, Point b) { return a.x * b.x + a.y * b.y; }
double Cross(Point a, Point b) { return a.x * b.y - a.y * b.x; }
int CCW(Point a, Point b, Point c) {
  Point d1 = b - a, d2 = c - a;
  if (int sign = Signum(Cross(d1, d2)))
    return sign; // 1:ccw,-1:cw
  if (Dot(d1, d2) < -EPS)
    return -2; // c-a-b
  if (Abs2(d1) < Abs2(d2) - EPS)
    return 2; // a-b-c
  return 0;   // a-c-b
}

bool IntersectSP(Segment s, Point p) {
  return CCW(s.pos, s.pos + s.dir, p) == 0;
}
bool IntersectSS(Segment a, Segment b) {
  int c1 = CCW(a.pos, a.pos + a.dir, b.pos),
      c2 = CCW(a.pos, a.pos + a.dir, b.pos + b.dir);
  int c3 = CCW(b.pos, b.pos + b.dir, a.pos),
      c4 = CCW(b.pos, b.pos + b.dir, a.pos + a.dir);
  return c1 * c2 <= 0 && c3 * c4 <= 0;
}
Point InterPointLL(Line a, Line b) {
  if (abs(Cross(a.dir, b.dir)) < EPS)
    return a.pos;
  return a.pos + Cross(b.pos - a.pos, b.dir) / Cross(a.dir, b.dir) * a.dir;
}
Point InterPointSS(Segment a, Segment b) {
  if (abs(Cross(a.dir, b.dir)) < EPS) {
    if (IntersectSP(b, a.pos))
      return a.pos;
    if (IntersectSP(b, a.pos + a.dir))
      return a.pos + a.dir;
    if (IntersectSP(a, b.pos))
      return b.pos;
    if (IntersectSP(a, b.pos + b.dir))
      return b.pos + b.dir;
  }
  return InterPointLL(a, b);
}

struct Edge {
  int src, dst;
  double weight;
  Edge() {}
  Edge(int s, int d, double w) : src(s), dst(d), weight(w) {}
  bool operator<(const Edge &e) const { return Signum(weight - e.weight) < 0; }
  bool operator>(const Edge &e) const { return Signum(weight - e.weight) > 0; }
};
typedef vector<vector<Edge>> Graph;

void SegmentArrangement(const vector<Segment> &ss, Graph &g,
                        vector<Point> &ps) {
  rep(i, ss.size()) {
    ps.push_back(ss[i].pos);
    ps.push_back(ss[i].pos + ss[i].dir);
    repi(j, i + 1, ss.size()) if (IntersectSS(ss[i], ss[j]))
        ps.push_back(InterPointSS(ss[i], ss[j]));
  }
  sort(all(ps), LessX());
  ps.erase(unique(all(ps)), ps.end());

  g.resize(ps.size());
  rep(i, ss.size()) {
    vector<pair<double, int>> ds;
    rep(j, ps.size()) if (IntersectSP(ss[i], ps[j]))
        ds.push_back(mp(Abs(ps[j] - ss[i].pos), j));
    sort(all(ds));
    rep(j, ds.size() - 1) {
      int u = ds[j].second, v = ds[j + 1].second;
      double w = ds[j + 1].first - ds[j].first;
      if (u >= g.size())
        throw "foo";
      if (v >= g.size())
        throw "bar";
      g[u].push_back(Edge(u, v, w));
      g[v].push_back(Edge(v, u, w));
    }
  }
}

int main() {
  for (int n; cin >> n, n;) {
    vector<Segment> ss(n);
    rep(i, n) {
      int x1, y1, x2, y2;
      cin >> x1 >> y1 >> x2 >> y2;
      ss[i] = Segment(x1, y1, x2 - x1, y2 - y1);
    }
    Point st, go;
    cin >> st.x >> st.y >> go.x >> go.y;

    Graph g;
    vector<Point> ps;
    SegmentArrangement(ss, g, ps);

    // vi sum(g.size());
    // repi(i,1,g.size())
    //	sum[i]=sum[i-1]+g[i-1].size();
    //
    // Graph g2(sum.back()+g.back().size());
    // rep(i,g.size()) rep(j,g[i].size()) rep(k,g[g[i][j].dst].size()){
    //	Edge e1=g[i][j],e2=g[g[i][j].dst][k];
    //	int u=sum[e1.src]+j,v=sum[e2.src]+k;
    //	double
    //w=abs(Arg(ps[e1.dst]-ps[e1.src])-Arg(ps[e2.dst]-ps[e2.src]))*180/PI;
    //	g2[u].emplace_back(u,v,w);
    // }
    //
    // vi sts,gos;
    // rep(i,g.size()) rep(j,g[i].size()){
    //	Segment seg(ps[i],ps[g[i][j].dst]-ps[i]);
    //	if(IntersectSP(seg,st)) sts.push_back(sum[i]+j);
    //	if(IntersectSP(seg,go)) gos.push_back(sum[i]+j);
    // }
    //
    // vd ws(g2.size(),INFTY);
    // priority_queue<Edge,vector<Edge>,greater<Edge>> pq;
    // rep(i,sts.size()) pq.emplace(-1,sts[i],0);
    // while(!pq.empty()){
    //	Edge cur=pq.top(); pq.pop();
    //	if(ws[cur.dst]!=INFTY) continue;
    //	ws[cur.dst]=cur.weight;
    //	for(Edge e:g2[cur.dst])
    //		pq.emplace(e.src,e.dst,cur.weight+e.weight);
    // }
    // double res=INFTY;
    // rep(i,gos.size()) res=min(res,ws[gos[i]]);
    //
    // if(res==INFTY) puts("-1");
    // else           printf("%f\\n",res);
  }

  return 0;
}