Language: C++

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

using namespace std;

typedef complex<double> P;
struct L { P p, q; L(P p, P q) : p(p), q(q) {} };

class Node {
public:
	int pos; double cost;
	Node(int pos, double cost) : pos(pos), cost(cost) {}
	bool operator < (const Node &nd) const { return cost > nd.cost; }
};

typedef vector< vector<Node> > graph;

const double EPS = 1e-8;

bool comp(const P &a, const P &b) {
	return make_pair(a.real(), a.imag()) < make_pair(b.real(), b.imag());
}

template <class T>
inline const T& abs(const T& a)
{
	return a > 0 ? a : -a;
}

double dot(P a, P b) { return real(conj(a)*b); }
double cross(P a, P b) { return imag(conj(a)*b); }

bool spIntersect(L l, P p){
	return abs(abs(l.p-p)+abs(p-l.q)-abs(l.p-l.q)) < EPS;
}

bool checkSign(L l, const vector<L> &sign){
	for(int i=0;i<sign.size();i++){
		L sg = sign[i];
		for(int j=0;j<2;j++){
			if(spIntersect(l, sg.p))
				return dot(l.q-l.p, sg.q-sg.p) < -EPS;
			swap(sg.p, sg.q);
		}
	}
	return true;
}

graph makeGraph(vector<P> &pt, const vector<L> &road, const vector<L> &sign){
	for(int i=0;i<road.size();i++){
		pt.push_back(road[i].p);
		pt.push_back(road[i].q);
	}
	sort(pt.begin(), pt.end(), comp);
	pt.erase(unique(pt.begin(), pt.end()), pt.end());
	graph g(pt.size());
	for(int i=0;i<road.size();i++){
		vector< pair<double, int> > vp;
		for(int j=0;j<pt.size();j++)
			if(spIntersect(road[i], pt[j]))
				vp.push_back(make_pair(abs(road[i].p-pt[j]), j));
		sort(vp.begin(), vp.end());
		for(int j=0;j+1<vp.size();j++){
			int a = vp[j].second, b = vp[j+1].second;
			if(checkSign(L(pt[a], pt[b]), sign)) g[a].push_back(Node(b, abs(pt[a]-pt[b])));
			if(checkSign(L(pt[b], pt[a]), sign)) g[b].push_back(Node(a, abs(pt[a]-pt[b])));
		}
	}
	return g;
}

void dijkstra(const graph &g, int s, int t, const vector<P> &vp){
	int n = g.size();
	vector<double> cost(n, 1e12); cost[s] = 0.0;
	vector<int> prev(n, -1);
	priority_queue<Node> qu; qu.push(Node(s, 0.0));
	while(!qu.empty()){
		Node nd = qu.top(); qu.pop();
		int pos = nd.pos;
		if(visit[pos]) continue;
		if(pos == t){
			vector<int> path;
			for(int p=t;p!=-1;p=prev[p]) path.push_back(p);
			reverse(path.begin(), path.end());
			for(int i=0;i<path.size();i++)
				printf("%d %d\n", int(real(vp[path[i]])+EPS), int(imag(vp[path[i]])+EPS));
			puts("0");	
			return ;
		}
		for(int i=0;i<g[pos].size();i++){
			int next = g[pos][i].pos;
			if(cost[pos] + g[pos][i].cost < cost[next]){
				cost[next] = cost[pos] + g[pos][i].cost;
				prev[next] = pos;
				qu.push(Node(next, cost[next]));
			}
		}
	}
	puts("-1");
}

int main(){
	int n;
	while(cin >> n, n){
		int xs, ys, xg, yg; cin >> xs >> ys >> xg >> yg;
		int x1, y1, x2, y2;
		vector<L> vl, road, sign;
		for(int i=0;i<n;i++){
			cin >> x1 >> y1 >> x2 >> y2;
			vl.push_back(L(P(x1,y1), P(x2,y2)));
		}
		for(int i=0;i<n;i++){
			bool bp = false, bq = false;
			for(int j=0;j<n;j++){
				if(i==j) continue;
				if(spIntersect(vl[j], vl[i].p)) bp = true;
				if(spIntersect(vl[j], vl[i].q)) bq = true;
			}
			if(bp&bq) road.push_back(vl[i]);
			else      sign.push_back(vl[i]);
		}
		vector<P> vp;
		graph g = makeGraph(vp, road, sign);
		int sidx, gidx;
		for(int i=0;i<vp.size();i++){
			if(abs(P(xs, ys)-vp[i]) < EPS) sidx = i;
			if(abs(P(xg, yg)-vp[i]) < EPS) gidx = i;
		}
		dijkstra(g, sidx, gidx, vp);
	}
}

Compiler output:
a.cc: In function 'void dijkstra(const graph&, int, int, const std::vector<std::complex<double> >&)':
a.cc:83:20: error: 'visit' was not declared in this scope
   83 |                 if(visit[pos]) continue;
      |                    ^~~~~
a.cc:6:1: note: 'std::visit' is defined in header '<variant>'; this is probably fixable by adding '#include <variant>'
    5 | #include <algorithm>
  +++ |+#include <variant>
    6 |