Language: C++

#include <iostream>
#include<string>
#include <complex>
#include<list>
#include<float.h>
#include <functional>
#include <hash_map.h>
//lib
using namespace std;
typedef complex<double> P;

#define REP(i,b,n) for(int i=b;i<n;i++)
#define REP0(i,n)   REP(i,0,n)

//foreachの中で内部を変更しないこと。
#define foreach(it,o) for(__typeof((o).begin()) it=(o).begin(); it!=(o).end(); ++it)

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

class geo {
public:
	static P zero;
	//a・b
	static double dot(P a, P b) {
		return real(conj(a) * b);
	}
	static double cross(P a, P b) {
		return imag(conj(a) * b);
	}
	//OA,OBの二辺のなす角
	//0<<180度
	static double theta(P a, P b) {
		return acos(dot(a, b) / (abs(a) * abs(b)));
	}
	//偏角
	static double theta(P a) {
		return arg(a);
	}
};
P geo::zero = P(0, 0);

// ３ 点をa → b → c と進むときの向き
int ccw(P a, P b, P c) {
	b -= a;
	c -= a;
	if (geo::cross(b, c) > DBL_EPSILON)
		return +1; // counter clockwise
	if (geo::cross(b, c) < -DBL_EPSILON)
		return -1; // clockwise
	if (geo::dot(b, c) < -DBL_EPSILON)
		return +2; // c--a--b on line
	if (norm(b) < norm(c) - DBL_EPSILON)
		return -2; // a--b--c on line
	return 0; // a--c--b on line (or b == c)
}

// 線分と線分の交差判定
bool IsIntersectSS(P a1, P a2, P b1, P b2) {
	return ccw(a1, a2, b1) * ccw(a1, a2, b2) <= 0
			&& ccw(b1, b2, a1) * ccw(b1, b2, a2) <= 0;
}

struct DP {
	P pos;
	P poll;
	double leedlen;
	double dist;
	DP(P pos, P poll, double leedlen, double dist) :
			pos(pos), poll(poll), leedlen(leedlen), dist(dist) {
	}
};
std::ostream& operator <<(std::ostream& os, const DP& v) {
	os << "(" << v.pos << ", " << v.poll << ", " << v.leedlen << ", " << v.dist
			<< ")";
	return os;
}

bool operator <(const DP& a, const DP& b) {
	return a.dist - b.dist;
}

int n;
P O = P(0, 0);
P D, F;
list<P> x;
list<DP> dp;
bool comparator(P l, P r) {
	if (abs(geo::theta(l, D) - geo::theta(r, D)) < DBL_EPSILON) {
		return abs(l) > abs(r);
	}
	return geo::theta(l, D) < geo::theta(r, D);
}
double px, py;
int main() {
	while (true) {
		cin >> n;
		x.clear();
		dp.clear();
		if (n == 0) {
			break;
		}
		cin >> px >> py;
		D = P(px, py);
		cin >> px >> py;
		F = P(px, py);
		double pos = geo::theta(D, F);

		REP0(i,n) {
			cin >> px >> py;
			P _x = P(px, py);
			if (pos > geo::theta(D, _x)) {
				x.push_back(_x);
			}
		}
		x.sort(comparator);
//		foreach(itx,x) {
//			cout<<*itx<<endl;
//		}

		if (abs(F) <= abs(D)) {
			dp.push_back(DP(D, O, abs(D), 0)); //初期位置

			foreach(itx,x) {
				list<DP> tmp;
				P _x = *itx;
				foreach(it,dp) {
					DP p = *it;
					if(p.pos==_x){
						continue;
					}
					//if (p.leedlen > abs(_x)) { //xの位置が遠過ぎない。　線分交差
					if (!IsIntersectSS(p.pos, F, p.poll, _x)) {
						//double l = p.leedlen - abs(_x);
						//if (abs(_x) + abs(F - _x) < p.leedlen) { //Pを跨いでも到着可能
						if (p.poll
								== O|| abs(arg(_x)-arg(p.poll))>=DBL_EPSILON) { //引っ掛ける場合。同じ角の場合引っ掛ける必要がない。

						(*it).leedlen -= abs(_x - p.poll);
						(*it).poll = _x;
					}

					for(list<P>::iterator itxx=itx;itxx!=x.end();itxx++){
						if(abs(arg(_x)-arg((*itxx)))<DBL_EPSILON && _x !=(*itxx)){
							tmp.push_back(
							DP((*itxx), p.poll, p.leedlen,
							p.dist + abs((*itxx) - p.pos))); //引っ掛けない場合。
						}
					}

						tmp.push_back(
								DP(_x, p.poll, p.leedlen,
										p.dist + abs(_x - p.pos))); //引っ掛けない場合。
				}
			}

				dp.merge(tmp);
//				foreach(it,dp) {
//					cout << *it << endl;
//				}
//				cout << " " << endl;
				tmp.clear();
			}

//			foreach(it,dp){
//				cout <<*it<<endl;
//			}
			//Fに必ず通す
			foreach(it,dp) {
				DP p = *it;
				(*it).dist += abs(F - p.pos);
				(*it).leedlen -= abs(F - p.poll);
				(*it).pos = F;
			}
//			foreach(it,dp) {
//				cout << *it << endl;
//			}
			double m = DBL_MAX;
			foreach(it,dp) {
				DP p = *it;
				if (p.leedlen >= 0)
					m = min(m, p.dist);
			}
			cout << m << endl;
		} else {
			cout << -1 << endl;
		}
	}
}

Compiler output:
a.cc:7:10: fatal error: hash_map.h: No such file or directory
    7 | #include <hash_map.h>
      |          ^~~~~~~~~~~~
compilation terminated.