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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <map>
#include <vector>
using namespace std;
int n, m, np, l, idx[100011], cl, q[100011], v, s, t;
double ans, eps = 1e-10;
bool f[100011], isstop[100011], mark[100011], flag;
struct recedge {
  int y, nxt;
} edge[2000011];
void build(int x, int y) {
  edge[++l].y = y;
  edge[l].nxt = idx[x];
  idx[x] = l;
}
struct couple {
  double x, y;
  couple(){};
  couple(const double &_a, const double &_b) : x(_a), y(_b) {}
  double len() { return sqrt(x * x + y * y); }
} b[1111], cp, points[100011];
bool equal(const double &a, const double &b) { return fabs(a - b) < eps; }
bool les(const double &a, const double &b) { return a + eps < b; }
bool operator<(const couple &a, const couple &b) {
  return les(a.x, b.x) or equal(a.x, b.x) and les(a.y, b.y);
}
bool operator==(const couple &a, const couple &b) {
  return equal(a.x, b.x) and equal(a.y, b.y);
}
map<couple, int> mp;
vector<couple> vec[311];
couple operator-(const couple &a, const couple &b) {
  return couple(a.x - b.x, a.y - b.y);
}
couple operator+(const couple &a, const couple &b) {
  return couple(a.x + b.x, a.y + b.y);
}

couple operator*(const double &lambda, const couple &a) {
  return couple(lambda * a.x, lambda * a.y);
}
double operator*(const couple &a, const couple &b) {
  return a.x * b.y - a.y * b.x;
}
double operator%(const couple &a, const couple &b) {
  return a.x * b.x + a.y * b.y;
}
struct reca {
  couple a, b;
} a[311];
bool cross(int i, int j) {
  if ((a[i].b - a[i].a) * (a[j].b - a[j].a) == 0) {
    if (a[i].b == a[j].a or a[i].b == a[j].b) {
      cp = a[i].b;
      return true;
    } else if (a[i].a == a[j].a or a[i].a == a[j].b) {
      cp = a[i].a;
      return true;
    }
    return false;
  } else if (((a[j].a - a[i].a) * (a[i].b - a[i].a)) *
                     ((a[j].b - a[i].a) * (a[i].b - a[i].a)) <=
                 0 and
             ((a[i].a - a[j].a) * (a[j].b - a[j].a)) *
                     ((a[i].b - a[j].a) * (a[j].b - a[j].a)) <=
                 0) {
    double lambda = (a[j].a - a[i].a) * (a[j].b - a[j].a) /
                    ((a[i].b - a[i].a) * (a[j].b - a[j].a));
    cp = a[i].a + lambda * (a[i].b - a[i].a);
    return true;
  } else
    return false;
}
bool on(int i, int j) {
  return (a[j].a - b[i]) * (a[j].b - b[i]) == 0 and
         (a[j].a - b[i]) % (a[j].b - b[i]) <= 0;
}
double dis(int i, int j) {
  return sqrt((points[i].x - points[j].x) * (points[i].x - points[j].x) +
              (points[i].y - points[j].y) * (points[i].y - points[j].y));
}
int main() {
  scanf("%d%d", &n, &m);
  ans = 0;
  for (int i = 1; i <= n; i++) {
    scanf("%lf%lf%lf%lf", &a[i].a.x, &a[i].a.y, &a[i].b.x, &a[i].b.y);
    if (a[i].a.x == a[i].b.x and a[i].a.y == a[i].b.y) {
      f[i] = false;
    } else
      f[i] = true;
    ans = ans + (a[i].b - a[i].a).len();
  }
  int n1 = 0;
  for (int i = 1; i <= n; i++)
    if (f[i])
      a[++n1] = a[i];
  n = n1;
  for (int i = 1; i <= m + 2; i++) {
    scanf("%lf%lf", &b[i].x, &b[i].y);
  }
  for (int i = 1; i <= n; i++) {
    vec[i].clear();
    vec[i].push_back(a[i].a);
    vec[i].push_back(a[i].b);
    mp[a[i].a] = 0;
    mp[a[i].b] = 0;
  }
  for (int i = 1; i <= n; i++)
    for (int j = i + 1; j <= n; j++)
      if (cross(i, j)) {
        vec[i].push_back(cp);
        vec[j].push_back(cp);
        mp[cp] = 0;
      }
  for (int i = 1; i <= m + 2; i++)
    for (int j = 1; j <= n; j++)
      if (on(i, j)) {
        vec[j].push_back(b[i]);
        mp[b[i]] = 0;
      }
  np = 0;
  for (map<couple, int>::iterator it = mp.begin(); it != mp.end(); it++) {
    it->second = ++np;
    points[np] = it->first;
  }
  l = 1;
  memset(idx, 0, sizeof(idx));
  for (int i = 1; i <= n; i++) {
    sort(vec[i].begin(), vec[i].end());
    vec[i].resize(unique(vec[i].begin(), vec[i].end()) - vec[i].begin());
    for (int j = 0; j < vec[i].size() - 1; j++) {
      build(mp[vec[i][j]], mp[vec[i][j + 1]]);
      build(mp[vec[i][j + 1]], mp[vec[i][j]]);
    }
    // for(int j = 0; j < vec[i].size(); j++) printf("%d ", mp[vec[i][j]]);
    // printf("\\n");
  }
  memset(isstop, 0, sizeof(isstop));
  memset(mark, 0, sizeof(mark));
  memset(f, true, sizeof(f));
  s = mp[b[m + 1]];
  t = mp[b[m + 2]];
  for (int i = 1; i <= m; i++)
    isstop[mp[b[i]]] = true;
  q[cl = 1] = t;
  flag = true;
  f[t] = false;
  for (int op = 1; op <= cl; op++) {
    // printf("%d\\n", q[op]);
    for (int p = idx[v = q[op]]; p; p = edge[p].nxt)
      if (f[edge[p].y] == true) {
        if (edge[p].y == s) {
          flag = false;
          break;
        } else {
          if (isstop[edge[p].y] == true) {
            mark[edge[p].y] = true;
            // printf("mark %d\\n", edge[p].y);
          } else {
            q[++cl] = edge[p].y;
            f[edge[p].y] = false;
          }
        }
      }
    if (flag == false)
      break;
  }
  if (flag == false) {
    printf("-1\\n");
    return 0;
  }
  q[cl = 1] = s;
  memset(f, true, sizeof(f));
  f[s] = false;
  for (int op = 1; op <= cl; op++) {
    for (int p = idx[v = q[op]]; p; p = edge[p].nxt) {
      ans -= dis(v, edge[p].y) / 2;
      if (mark[edge[p].y] == true)
        ans -= dis(v, edge[p].y) / 2;
      else if (f[edge[p].y]) {
        f[edge[p].y] = false;
        q[++cl] = edge[p].y;
      }
    }
  }
  printf("%.10f\\n", ans);
  fclose(stdin);
  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <map>
#include <vector>
using namespace std;
int n, m, np, l, idx[100011], cl, q[100011], v, s, t;
double ans, eps = 1e-10;
bool f[100011], isstop[100011], mark[100011], flag;
struct recedge {
  int y, nxt;
} edge[2000011];
void build(int x, int y) {
  edge[++l].y = y;
  edge[l].nxt = idx[x];
  idx[x] = l;
}
struct couple {
  double x, y;
  couple(){};
  couple(const double &_a, const double &_b) : x(_a), y(_b) {}
  double len() { return sqrt(x * x + y * y); }
} b[1111], cp, points[100011];
bool equal(const double &a, const double &b) { return fabs(a - b) < eps; }
bool les(const double &a, const double &b) { return a + eps < b; }
bool operator<(const couple &a, const couple &b) {
  return les(a.x, b.x) or equal(a.x, b.x) and les(a.y, b.y);
}
bool operator==(const couple &a, const couple &b) {
  return equal(a.x, b.x) and equal(a.y, b.y);
}
map<couple, int> mp;
vector<couple> vec[111];
couple operator-(const couple &a, const couple &b) {
  return couple(a.x - b.x, a.y - b.y);
}
couple operator+(const couple &a, const couple &b) {
  return couple(a.x + b.x, a.y + b.y);
}

couple operator*(const double &lambda, const couple &a) {
  return couple(lambda * a.x, lambda * a.y);
}
double operator*(const couple &a, const couple &b) {
  return a.x * b.y - a.y * b.x;
}
double operator%(const couple &a, const couple &b) {
  return a.x * b.x + a.y * b.y;
}
struct reca {
  couple a, b;
} a[311];
bool cross(int i, int j) {
  if ((a[i].b - a[i].a) * (a[j].b - a[j].a) == 0) {
    if (a[i].b == a[j].a or a[i].b == a[j].b) {
      cp = a[i].b;
      return true;
    } else if (a[i].a == a[j].a or a[i].a == a[j].b) {
      cp = a[i].a;
      return true;
    }
    return false;
  } else if (((a[j].a - a[i].a) * (a[i].b - a[i].a)) *
                     ((a[j].b - a[i].a) * (a[i].b - a[i].a)) <=
                 0 and
             ((a[i].a - a[j].a) * (a[j].b - a[j].a)) *
                     ((a[i].b - a[j].a) * (a[j].b - a[j].a)) <=
                 0) {
    double lambda = (a[j].a - a[i].a) * (a[j].b - a[j].a) /
                    ((a[i].b - a[i].a) * (a[j].b - a[j].a));
    cp = a[i].a + lambda * (a[i].b - a[i].a);
    return true;
  } else
    return false;
}
bool on(int i, int j) {
  return (a[j].a - b[i]) * (a[j].b - b[i]) == 0 and
         (a[j].a - b[i]) % (a[j].b - b[i]) <= 0;
}
double dis(int i, int j) {
  return sqrt((points[i].x - points[j].x) * (points[i].x - points[j].x) +
              (points[i].y - points[j].y) * (points[i].y - points[j].y));
}
int main() {
  scanf("%d%d", &n, &m);
  ans = 0;
  for (int i = 1; i <= n; i++) {
    scanf("%lf%lf%lf%lf", &a[i].a.x, &a[i].a.y, &a[i].b.x, &a[i].b.y);
    ans = ans + (a[i].b - a[i].a).len();
  }
  for (int i = 1; i <= m + 2; i++) {
    scanf("%lf%lf", &b[i].x, &b[i].y);
  }
  for (int i = 1; i <= n; i++) {
    vec[i].clear();
    vec[i].push_back(a[i].a);
    vec[i].push_back(a[i].b);
    mp[a[i].a] = 0;
    mp[a[i].b] = 0;
  }
  for (int i = 1; i <= n; i++)
    for (int j = i + 1; j <= n; j++)
      if (cross(i, j)) {
        vec[i].push_back(cp);
        vec[j].push_back(cp);
        mp[cp] = 0;
      }
  for (int i = 1; i <= m + 2; i++)
    for (int j = 1; j <= n; j++)
      if (on(i, j)) {
        vec[j].push_back(b[i]);
        mp[b[i]] = 0;
      }
  np = 0;
  for (map<couple, int>::iterator it = mp.begin(); it != mp.end(); it++) {
    it->second = ++np;
    points[np] = it->first;
  }
  l = 1;
  memset(idx, 0, sizeof(idx));
  for (int i = 1; i <= n; i++) {
    sort(vec[i].begin(), vec[i].end());
    vec[i].resize(unique(vec[i].begin(), vec[i].end()) - vec[i].begin());
    for (int j = 0; j < vec[i].size() - 1; j++) {
      build(mp[vec[i][j]], mp[vec[i][j + 1]]);
      build(mp[vec[i][j + 1]], mp[vec[i][j]]);
    }
    // for(int j = 0; j < vec[i].size(); j++) printf("%d ", mp[vec[i][j]]);
    // printf("\\n");
  }
  memset(isstop, 0, sizeof(isstop));
  memset(mark, 0, sizeof(mark));
  memset(f, true, sizeof(f));
  s = mp[b[m + 1]];
  t = mp[b[m + 2]];
  for (int i = 1; i <= m; i++)
    isstop[mp[b[i]]] = true;
  q[cl = 1] = t;
  flag = true;
  f[t] = false;
  for (int op = 1; op <= cl; op++) {
    // printf("%d\\n", q[op]);
    for (int p = idx[v = q[op]]; p; p = edge[p].nxt)
      if (f[edge[p].y] == true) {
        if (edge[p].y == s) {
          flag = false;
          break;
        } else {
          if (isstop[edge[p].y] == true) {
            mark[edge[p].y] = true;
            // printf("mark %d\\n", edge[p].y);
          } else {
            q[++cl] = edge[p].y;
            f[edge[p].y] = false;
          }
        }
      }
    if (flag == false)
      break;
  }
  if (flag == false) {
    printf("-1\\n");
    return 0;
  }
  q[cl = 1] = s;
  memset(f, true, sizeof(f));
  f[s] = false;
  for (int op = 1; op <= cl; op++) {
    for (int p = idx[v = q[op]]; p; p = edge[p].nxt) {
      ans -= dis(v, edge[p].y) / 2;
      if (mark[edge[p].y] == true)
        ans -= dis(v, edge[p].y) / 2;
      else if (f[edge[p].y]) {
        f[edge[p].y] = false;
        q[++cl] = edge[p].y;
      }
    }
  }
  printf("%.10f\\n", ans);
  fclose(stdin);
  return 0;
}