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

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;

#define reps(i, f, n) for (int i = f; i < int(n); i++)
#define rep(i, n) reps(i, 0, n)

#define X real()
#define Y imag()

const int INF = 1000000007;
const double EPS = 0.00001;
const int N = 222;
const int M = 444;

typedef pair<int, int> pii;

typedef complex<double> P;
class L : public vector<P> {
public:
  L(P a, P b) {
    push_back(a);
    push_back(b);
  }
  L() {
    push_back(P());
    push_back(P());
  }
};

double dot(P a, P b) { return a.X * b.X + a.Y * b.Y; }
double cross(P a, P b) { return a.X * b.Y - a.Y * b.X; }

double dist_LP(L a, P b) {
  P e = a[1] - a[0];
  e = e / abs(e);

  double alen = abs(a[1] - a[0]);

  double d = dot(b - a[0], e);
  if (d < 0 || d >= alen) {
    return min(abs(b - a[0]), abs(b - a[1]));
  }

  double f = abs(b - a[0]);
  return sqrt(max(0.0, f * f - d * d));
}

int n;
P st, en;
vector<L> line;

bool input() {

  cin >> n;
  if (n == 0)
    return false;

  double a, b, c, d;
  cin >> a >> b >> c >> d;
  st = P(a, b);
  en = P(c, d);

  line.clear();
  rep(i, n) {
    cin >> a >> b >> c >> d;
    line.push_back(L(P(a, b), P(c, d)));
  }
  return true;
}

vector<L> road;
vector<L> sign;

void inputsplit() {
  road.clear();
  sign.clear();
  rep(i, line.size()) {
    bool hita = false;
    bool hitb = false;
    rep(j, line.size()) {
      if (i == j)
        continue;
      if (dist_LP(line[j], line[i][0]) < EPS)
        hita = true;
      if (dist_LP(line[j], line[i][1]) < EPS)
        hitb = true;
    }
    if (hita && hitb)
      road.push_back(line[i]);
    else
      sign.push_back(line[i]);
  }
}

void inputsplit2() {
  vector<vector<L>> copy;
  rep(i, road.size()) {
    vector<L> ex(1);
    ex[0] = road[i];

    rep(j, road.size()) {
      if (i == j)
        continue;
      rep(k, ex.size()) {
        bool ok = false;
        P point(0, 0);

        rep(p, 2) {
          double d = dist_LP(ex[k], road[j][p]);
          if (d < EPS) {
            ok = true;
            point = road[j][p];
          }
        }
        if (ok && min(abs(ex[k][0] - point), abs(ex[k][1] - point)) > EPS) {
          L bef = ex[k];
          ex.erase(ex.begin() + k);
          k--;
          ex.push_back(L(bef[0], point));
          ex.push_back(L(bef[1], point));
        }
      }
    }
    copy.push_back(ex);
  }
  vector<L> res;
  rep(i, copy.size()) { rep(j, copy[i].size()) res.push_back(copy[i][j]); }
  road = res;
}

map<pii, int> table;
int tonum(P pos) {
  pii p = pii(int(pos.X + 0.5), int(pos.Y + 0.5));
  if (table.find(p) == table.end()) {
    table[p] = 0;
    table[p] = table.size() - 1;
  }
  return table[p];
}
P topos(int num) {
  for (map<pii, int>::iterator it = table.begin(); it != table.end(); it++) {
    if (it->second == num)
      return P(it->first.first, it->first.second);
  }
  return P(INF, INF);
}

void setroadnum() {
  rep(i, road.size()) {
    tonum(road[i][0]);
    tonum(road[i][1]);
  }
}

double edge[M][M];
void setEdge() {
  rep(i, M) rep(j, M) edge[i][j] = INF;
  rep(i, M) edge[i][i] = 0;

  rep(i, road.size()) {
    int a = tonum(road[i][0]);
    int b = tonum(road[i][1]);
    double len = abs(road[i][1] - road[i][0]);
    edge[a][b] = edge[b][a] = len;

    rep(j, sign.size()) {
      bool ok = false;
      bool rev = false;
      rep(k, 2) {
        if (dist_LP(road[i], sign[j][k]) < EPS) {
          ok = true;
          if (k == 1)
            rev = true;
        }
      }

      if (ok) {
        L s = sign[j];
        if (rev) {
          swap(s[0], s[1]);
        }
        double dval = dot(road[i][1] - road[i][0], s[1] - s[0]);
        if (dval < EPS)
          edge[b][a] = INF;
        if (dval > -EPS)
          edge[a][b] = INF;
      }
    }
  }
}

double dp[M][M];
vector<P> wf() {
  rep(i, M) rep(j, M) dp[i][j] = edge[i][j];

  int m = table.size();
  rep(k, m) rep(i, m) rep(j, m) dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);

  int stnum = tonum(st);
  int ennum = tonum(en);

  vector<P> ret;
  if (dp[stnum][ennum] > INF - EPS)
    return ret;

  ret.push_back(topos(ennum));
  while (1) {
    if (ennum == stnum)
      break;
    rep(i, m) {
      if (i == ennum)
        continue;
      double d = edge[i][ennum] - (dp[stnum][ennum] - dp[stnum][i]);
      if (abs(d) < EPS) {
        ret.push_back(topos(i));
        ennum = i;
        break;
      }
    }
  }

  reverse(ret.begin(), ret.end());
  return ret;
}

vector<P> solve() {
  table.clear();
  inputsplit();
  inputsplit2();

  setroadnum();

  setEdge();
  vector<P> ret = wf();
  return ret;
}

void call() {
  vector<P> res = solve();
  if (res.size() == 0)
    puts("-1");
  else {
    rep(i, res.size()) {
      printf("%d %d\\n", int(res[i].X + 0.5), int(res[i].Y + 0.5));
    }
    puts("0");
  }
}

int main() {
  while (input())
    call();
}

Error: WA

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

using namespace std;

#define reps(i, f, n) for (int i = f; i < int(n); i++)
#define rep(i, n) reps(i, 0, n)

#define X real()
#define Y imag()

const int INF = 1000000007;
const double EPS = 0.0000001;
const int N = 222;
const int M = 444;

typedef pair<int, int> pii;

typedef complex<double> P;
class L : public vector<P> {
public:
  L(P a, P b) {
    push_back(a);
    push_back(b);
  }
  L() {
    push_back(P());
    push_back(P());
  }
};

double dot(P a, P b) { return a.X * b.X + a.Y * b.Y; }
double cross(P a, P b) { return a.X * b.Y - a.Y * b.X; }

double dist_LP(L a, P b) {
  P e = a[1] - a[0];

  if (abs(e) < EPS)
    return abs(b - a[1]);
  e = e / abs(e);

  double alen = abs(a[1] - a[0]);

  double d = dot(b - a[0], e);
  if (d < 0 || d >= alen) {
    return min(abs(b - a[0]), abs(b - a[1]));
  }

  double f = abs(b - a[0]);
  return sqrt(f * f - d * d);
}

bool same(P a, P b) { return abs(a - b) < 0.000001; }

int n;
P st, en;
vector<L> line;

bool input() {

  cin >> n;
  if (n == 0)
    return false;

  double a, b, c, d;
  cin >> a >> b >> c >> d;
  st = P(a, b);
  en = P(c, d);

  line.clear();
  rep(i, n) {
    cin >> a >> b >> c >> d;
    line.push_back(L(P(a, b), P(c, d)));
  }
  return true;
}

vector<L> road;
vector<L> sign;

void inputsplit() {
  road.clear();
  sign.clear();
  rep(i, line.size()) {
    bool hita = false;
    bool hitb = false;
    rep(j, line.size()) {
      if (i == j)
        continue;
      if (dist_LP(line[j], line[i][0]) < EPS)
        hita = true;
      if (dist_LP(line[j], line[i][1]) < EPS)
        hitb = true;
    }
    if (hita && hitb)
      road.push_back(line[i]);
    else
      sign.push_back(line[i]);
  }
}

void inputsplit2() {
  vector<vector<L>> copy;
  rep(i, road.size()) {
    vector<L> ex(1);
    ex[0] = road[i];

    rep(j, road.size()) {
      if (i == j)
        continue;
      rep(k, ex.size()) {
        bool ok = false;
        P point(0, 0);

        rep(p, 2) {
          double d = dist_LP(ex[k], road[j][p]);
          if (d < EPS) {
            ok = true;
            point = road[j][p];
          }
        }
        if (ok && min(abs(ex[k][0] - point), abs(ex[k][1] - point)) > EPS) {
          L bef = ex[k];
          ex.erase(ex.begin() + k);
          k--;
          ex.push_back(L(bef[0], point));
          ex.push_back(L(bef[1], point));
        }
      }
    }
    copy.push_back(ex);
  }
  vector<L> res;
  rep(i, copy.size()) { rep(j, copy[i].size()) res.push_back(copy[i][j]); }
  road = res;
}

map<pii, int> table;
int tonum(P pos) {
  pii p = pii(int(pos.X + 0.5), int(pos.Y + 0.5));
  if (table.find(p) == table.end()) {
    table[p] = 0;
    table[p] = table.size() - 1;
  }
  return table[p];
}
P topos(int num) {
  for (map<pii, int>::iterator it = table.begin(); it != table.end(); it++) {
    if (it->second == num)
      return P(it->first.first, it->first.second);
  }
  return P(INF, INF);
}

void setroadnum() {
  rep(i, road.size()) {
    tonum(road[i][0]);
    tonum(road[i][1]);
  }
}

double edge[M][M];
void setEdge() {
  rep(i, M) rep(j, M) edge[i][j] = INF;
  rep(i, M) edge[i][i] = 0;

  rep(i, road.size()) {
    int a = tonum(road[i][0]);
    int b = tonum(road[i][1]);
    double len = abs(road[i][1] - road[i][0]);
    edge[a][b] = edge[b][a] = len;

    rep(j, sign.size()) {
      bool ok = false;
      bool rev = false;
      rep(k, 2) {
        if (dist_LP(road[i], sign[j][k]) < EPS) {
          ok = true;
          if (k == 1)
            rev = true;
        }
      }

      if (ok) {
        L s = sign[j];
        if (rev) {
          swap(s[0], s[1]);
        }
        double dval = dot(road[i][1] - road[i][0], s[1] - s[0]);
        if (dval < EPS)
          edge[b][a] = INF;
        if (dval > -EPS)
          edge[a][b] = INF;
      }
    }
  }
}

double dp[M][M];
vector<P> wf() {
  rep(i, M) rep(j, M) dp[i][j] = edge[i][j];

  int m = table.size();
  rep(k, m) rep(i, m) rep(j, m) dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);

  int stnum = tonum(st);
  int ennum = tonum(en);

  vector<P> ret;
  if (dp[stnum][ennum] > INF - EPS)
    return ret;

  ret.push_back(topos(ennum));
  while (1) {
    if (ennum == stnum)
      break;
    rep(i, m) {
      if (i == ennum)
        continue;
      double d = edge[i][ennum] - (dp[stnum][ennum] - dp[stnum][i]);
      if (abs(d) < EPS * 10) {
        ret.push_back(topos(i));
        ennum = i;
        break;
      }
    }
  }

  reverse(ret.begin(), ret.end());
  return ret;
}

vector<P> solve() {
  inputsplit();
  inputsplit2();

  setroadnum();

  setEdge();

  /*
  puts("road hoge");
  rep(i,road.size()){
          cout<<road[i][0]<<" "<<road[i][1]<<endl;
  }
  puts("sign hoge");
  rep(i,sign.size()){
          cout<<sign[i][0]<<" "<<sign[i][1]<<endl;
  }

  puts("road points");
  for(map<pii,int>::iterator it = table.begin(); it!=table.end(); it++){
          cout<<"*"<<it->first.first<<" "<<it->first.second<<"
  "<<it->second<<endl;
  }


  int m = table.size();
  rep(i,m){
          rep(j,m){
                  if(edge[i][j]>INF-EPS)printf("-.--- ");
                  else printf("%3.3lf ",edge[i][j]);
          }puts("");
  }
  */

  vector<P> ret = wf();
  return ret;
}

void call() {
  vector<P> res = solve();
  if (res.size() == 0)
    puts("-1");
  else {
    rep(i, res.size()) {
      printf("%d %d\\n", int(res[i].X + 0.5), int(res[i].Y + 0.5));
    }
  }
}

int main() {
  while (input())
    call();
}
/*
11
5 5
1 0
3 1 5 1
4 3 4 2
3 1 5 5
2 3 2 2
1 0 1 2
1 2 3 4
3 4 5 5
1 0 5 2
4 0 4 1
5 5 5 1
2 3 2 4
0

*/