Language: C++

#include <iostream>
#include <vector>
#include <complex>
#include <algorithm>
#include <map>
#include <queue>

using namespace std;
typedef complex<double> Point;
struct Segment{ Point p1, p2; };
typedef Segment Line;
const double EPS = 1e-8;
const double INF = 1e50;

bool equals(double a, double b){
  return abs(a - b) < EPS;
}

double getDistance(Point a, Point b){
  return abs(a - b);
}

bool isCover(Segment s, Point p){
  return getDistance(s.p1, p) + getDistance(p, s.p2) < getDistance(s.p1, s.p2) + EPS;
}

double dot(Point a, Point b){
  return real(conj(a) * b);
}

double cross(Point a, Point b){
  return imag(conj(a) * b);
}

int ccw(Point p0, Point p1, Point p2){
  Point a = p1 - p0;
  Point b = p2 - p0;
  if(cross(a, b) > EPS) return 1;
  if(cross(a, b) < -EPS) return -1;
  if(dot(a, b) < -EPS) return 2;
  if(norm(a) < norm(b)) return -2;
  return 0;
}

bool isIntersect(Point p1, Point p2, Point p3, Point p4){
  return (ccw(p1, p2, p3) * ccw(p1, p2, p4) <= 0 &&
          ccw(p3, p4, p1) * ccw(p3, p4, p2) <= 0);
}

bool isIntersect(Segment s1, Segment s2){
  return isIntersect(s1.p1, s1.p2, s2.p1, s2.p2);
}

Point getCrossPoint(Segment s1, Segment s2){
  Point base = s2.p2 - s2.p1;
  double d1 = abs(cross(base, s1.p1 - s2.p1));
  double d2 = abs(cross(base, s1.p2 - s2.p1));
  double t = d1 / (d1 + d2);
  return s1.p1 + (s1.p2 - s1.p1) * t;
}

void arrangement(const vector<Segment>& S, vector<Point>& P, vector<int>* G){
  int n = S.size();
  P.clear();
  vector<pair<double, double> > tmp;
  for(int i=0;i<n;i++){
    tmp.push_back(make_pair(S[i].p1.real(), S[i].p1.imag()));
    tmp.push_back(make_pair(S[i].p2.real(), S[i].p2.imag()));
    for(int j=0;j<i;j++){
      if(isIntersect(S[i], S[j])){
        Point t = getCrossPoint(S[i], S[j]);
        tmp.push_back(make_pair(t.real(), t.imag()));
      }
    }
  }
  Point a, b;
  sort(tmp.begin(), tmp.end());
  tmp.erase(unique(tmp.begin(), tmp.end()), tmp.end());
  for(int i=0;i<tmp.size();i++) P.push_back(Point(tmp[i].first, tmp[i].second));
  for(int i=0;i<n;i++){
    vector<int> on;
    for(int u=0;u<P.size();u++){
      if(isCover(S[i], P[u])) on.push_back(u);
      for(int j=0;j<(int)on.size()-1;j++){
        int u = on[j], v = on[j+1];
        G[u].push_back(v);
        G[v].push_back(u);
      }
    }
  }
}

bool can_pass(const Point& s, const Point& t, const vector<Segment>& sign){
  int n = sign.size();
  Segment R = {s, t};
  for(int i=0;i<n;i++){
    Segment S = sign[i];
    if(isCover(R, S.p1) && dot(s - S.p1, S.p2 - S.p1) <= 0) return false;
    if(isCover(R, S.p2) && dot(s - S.p2, S.p1 - S.p2) <= 0) return false;
  }
  return true;
}

main(){
  int n;
  while(cin >> n && n){
    vector<Segment> seg;
    Point s, g;
    cin >> s.real() >> s.imag();
    cin >> g.real() >> g.imag();
    for(int i=0;i<n;i++){
      Segment in;
      cin >> in.p1.real() >> in.p1.imag() >> in.p2.real() >> in.p2.imag();
      seg.push_back(in);
    }
    vector<Segment> road, sign;
    for(int i=0;i<n;i++){
      bool f[2] = {false, false};
      for(int j=0;j<n;j++){
        if(i == j) continue;
        if(isCover(seg[j], seg[i].p1)) f[0] = true;
        if(isCover(seg[j], seg[i].p2)) f[1] = true;
      }
      if(f[0] && f[1]) road.push_back(seg[i]);
      else sign.push_back(seg[i]);
    }
    vector<Point> P;
    vector<int> G[400];
    arrangement(road, P, G);
    int N = P.size();
    int s_id = find(P.begin(), P.end(), s) - P.begin();
    int g_id = find(P.begin(), P.end(), g) - P.begin();

    int path[400];
    double d[400];
    for(int u=0;u<N;u++) d[u] = (u == s_id ? 0 : INF);
    priority_queue<pair<double, int> > Q;
    Q.push(make_pair(0, s_id));
    while(!Q.empty()){
      double d_now = -Q.top().first;
      int u = Q.top().second;
      Q.pop();
      if(d[u] < d_now - EPS) continue;
      
      for(int i=0;i<G[u].size();i++){
        int v = G[u][i];
        double cost = getDistance(P[u], P[v]);
        if(d[v] - EPS > d[u] + cost && can_pass(P[u], P[v], sign)){
          d[v] = d[u] + cost;
          path[v] = u;
          Q.push(make_pair(-d[v], v));
        }
      }
    }
    
    if(d[g_id] > INF / 2) puts("-1");
    else{
      vector<int> ans(1, g_id);
      int u = g_id;
      while(u != s_id) u = path[u], ans.push_back(u);
      reverse(ans.begin(), ans.end());
      for(int i=0;i<ans.size();i++){
        printf("%.0f %.0f\n", P[ans[i]].real(), P[ans[i]].imag());
      }
      puts("0");
    }
  }
}

Compiler output:
a.cc:104:1: warning: ISO C++ forbids declaration of 'main' with no type [-Wreturn-type]
  104 | main(){
      | ^~~~
a.cc: In function 'int main()':
a.cc:109:9: error: no match for 'operator>>' (operand types are 'std::istream' {aka 'std::basic_istream<char>'} and 'double')
  109 |     cin >> s.real() >> s.imag();
      |     ~~~ ^~ ~~~~~~~~
      |     |            |
      |     |            double
      |     std::istream {aka std::basic_istream<char>}
In file included from /usr/include/c++/14/iostream:42,
                 from a.cc:1:
/usr/include/c++/14/istream:170:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(bool&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  170 |       operator>>(bool& __n)
      |       ^~~~~~~~
/usr/include/c++/14/istream:170:7: note:   conversion of argument 1 would be ill-formed:
a.cc:109:18: error: cannot bind non-const lvalue reference of type 'bool&' to a value of type 'double'
  109 |     cin >> s.real() >> s.imag();
      |            ~~~~~~^~
/usr/include/c++/14/istream:174:7: note: candidate: 'std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(short int&) [with _CharT = char; _Traits = std::char_traits<char>]' (near match)
  174 |       operator>>(short& __n);
      |       ^~~~~~~~
/usr/include/c++/14/istream:174:7: note:   conversion of argument 1 would be ill-formed:
a.cc:109:18: error: cannot bind non-const lvalue reference of type 'short int&' to a value of type 'double'
  109 |     cin >> s.real() >> s.imag();
      |            ~~~~~~^~
/usr/include/c++/14/istream:177:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(short unsigned int&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  177 |       operator>>(unsigned short& __n)
      |       ^~~~~~~~
/usr/include/c++/14/istream:177:7: note:   conversion of argument 1 would be ill-formed:
a.cc:109:18: error: cannot bind non-const lvalue reference of type 'short unsigned int&' to a value of type 'double'
  109 |     cin >> s.real() >> s.imag();
      |            ~~~~~~^~
/usr/include/c++/14/istream:181:7: note: candidate: 'std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(int&) [with _CharT = char; _Traits = std::char_traits<char>]' (near match)
  181 |       operator>>(int& __n);
      |       ^~~~~~~~
/usr/include/c++/14/istream:181:7: note:   conversion of argument 1 would be ill-formed:
a.cc:109:18: error: cannot bind non-const lvalue reference of type 'int&' to a value of type 'double'
  109 |     cin >> s.real() >> s.imag();
      |            ~~~~~~^~
/usr/include/c++/14/istream:184:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(unsigned int&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  184 |       operator>>(unsigned int& __n)
      |       ^~~~~~~~
/usr/include/c++/14/istream:184:7: note:   conversion of argument 1 would be ill-formed:
a.cc:109:18: error: cannot bind non-const lvalue reference of type 'unsigned int&' to a value of type 'double'
  109 |     cin >> s.real() >> s.imag();
      |            ~~~~~~^~
/usr/include/c++/14/istream:188:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long int&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  188 |       operator>>(long& __n)
      |       ^~~~~~~~
/usr/include/c++/14/istream:188:7: note:   conversion of argument 1 would be ill-formed:
a.cc:109:18: error: cannot bind non-const lvalue reference of type 'long int&' to a value of type 'double'
  109 |     cin >> s.real() >> s.imag();
      |            ~~~~~~^~
/usr/include/c++/14/istream:192:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long unsigned int&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  192 |       operator>>(unsigned long& __n)
      |       ^~~~~~~~
/usr/include/c++/14/istream:192:7: note:   conversion of argument 1 would be ill-formed:
a.cc:109:18: error: cannot bind non-const lvalue reference of type 'long unsigned int&' to a value of type 'double'
  109 |     cin >> s.real() >> s.imag();
      |            ~~~~~~^~
/usr/include/c++/14/istream:199:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long long int&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  199 |       operator>>(long long& __n)
      |       ^~~~~~~~
/usr/include/c++/14/istream:199:7: note:   conversion of argument 1 would be ill-formed:
a.cc:109:18: error: cannot bind non-const lvalue reference of type 'long long int&' to a value of type 'double'
  109 |     cin >> s.real() >> s.imag();
      |            ~~~~~~^~
/usr/include/c++/14/istream:203:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long long unsigned int&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  203 |       operator>>(unsigned long long& __n)
      |       ^~~~~~~~
/usr/include/c++/14/istream:203:7: note:   conversion of argument 1 would be ill-formed:
a.cc:109:18: error: cannot bind non-const lvalue reference of type 'long long unsigned int&' to a value of type 'double'
  109 |     cin >> s.real() >> s.imag();
      |            ~~~~~~^~
/usr/include/c++/14/istream:219:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(float&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  219 |       operator>>(float& __f)
      |       ^~~~~~~~
/usr/include/c++/14/istream:219:7: note:   conversion of argument 1 would be ill-formed:
a.cc:109:18: error: cannot bind non-const lvalue reference of type 'float&' to a value of type 'double'
  109 |     cin >> s.real() >> s.imag();
      |            ~~~~~~^~
/usr/include/c++/14/istream:223:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(double&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  223 |       operator>>(double& __f)
      |       ^~~~~~~~
/usr/include/c++/14/istream:223:7: note:   conversion of argument 1 would be ill-formed:
a.cc:109:18: error: cannot bind non-const lvalue reference of type 'double&' to an rvalue of type 'double'
  109 |     cin >> s.real() >> s.imag();
      |            ~~~~~~^~
/usr/include/c++/14/istream:227:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long double&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]' (near match)
  227 |       operator>>(long double& __f)
      |       ^~~~~~~~
/usr/include/c++/14/istream:227:7: note:   conversion of argument 1 would be ill-formed:
a.cc:109:18: error: cannot bind non-const lvalue reference of type 'long double&' to a value of type 'double'
  109 |     cin >> s.real() >> s.imag();
      |            ~~~~~~^~
/usr/include/c++/14/istream:328:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(void*&) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]'
  328 |       operator>>(void*& __p)
      |       ^~~~~~~~
/usr/include/c++/14/istream:328:25: note:   no known conversion for argument 1 from 'double' to 'void*&'
  328 |       operator>>(void*& __p)
      |                  ~~~~~~~^~~
/usr/include/c++/14/istream:122:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(__istream_type& (*)(__istream_type&)) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]'
  122 |       operator>>(__istream_type& (*__pf)(__istream_type&))
      |       ^~~~~~~~
/usr/include/c++/14/istream:122:36: note:   no known conversion for argument 1 from 'double' to 'std::basic_istream<char>::__istream_type& (*)(std::basic_istream<char>::__istream_type&)' {aka 'std::basic_istream<char>& (*)(std::basic_istream<char>&)'}
  122 |       operator>>(__istream_type& (*__pf)(__istream_type&))
      |                  ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/14/istream:126:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(__ios_type& (*)(__ios_type&)) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>; __ios_type = std::basic_ios<char>]'
  126 |       operator>>(__ios_type& (*__pf)(__ios_type&))
      |       ^~~~~~~~
/usr/include/c++/14/istream:126:32: note:   no known conversion for argument 1 from 'double' to 'std::basic_istream<char>::__ios_type& (*)(std::basic_istream<char>::__ios_type&)' {aka 'std::basic_ios<char>& (*)(std::basic_ios<char>&)'}
  126 |       operator>>(__ios_type& (*__pf)(__ios_type&))
      |                  ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
/usr/include/c++/14/istream:133:7: note: candidate: 'std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::ios_base& (*)(std::ios_base&)) [with _CharT = char; _Traits = std::char_traits<char>; __istream_type = std::basic_istream<char>]'
  133 |       operator>>(ios_base& (*__pf)(ios_base&))
      |       ^~~~~~~~
/usr/include/c++/14/istream:133:30: note:   no known conversion for argument 1 from 'double' t