Language: C++

#include <queue>
#include <set>
#include <unordered_set>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef pair<int,int> pii;

/// pair<int,int> hasher
namespace std{
	template<typename I>
	class hash<pair<I,I>>{
		public:
		size_t operator()(const pair<I,I> &p) const {return hash<long long>() (((long long)(p.first))<<32|p.second);}
	};
}

double solve(const vector<pii> &a){
	set<int>ys;
	for(auto &e:a)ys.insert(e.second);
	int n=a.size();
	vector<double>mx,my;
	for(int i=0;i<n;i++){
		mx.push_back(a[i].first);
		my.push_back(a[i].second);
		if(i==n-1)continue;
		if(a[i].second<a[i+1].second){ //??????i????°???§??????
			for(auto it=ys.begin();it!=ys.end();++it){
				if(a[i].second<*it && *it<a[i+1].second){
					double dy=a[i+1].second-a[i].second;
					double dx=(a[i+1].first-a[i].first)/dy*(*it-a[i].second);
					mx.push_back(a[i].first+dx);
					my.push_back(*it);
				}
			}
		}else{ //??????i????±±??§??????
			for(auto it=ys.end();it--!=ys.begin();){
				if(a[i+1].second<*it && *it<a[i].second){
					double dy=a[i+1].second-a[i].second;
					double dx=(a[i+1].first-a[i].first)/dy*(*it-a[i].second);
					mx.push_back(a[i].first+dx);
					my.push_back(*it);
				}
			}
		}
	}
	int m=mx.size();
	priority_queue<pair<double,pii>>q;
	unordered_set<pii>se;
	q.push({0,{0,m-1}});
	for(;!q.empty();){
		double c=q.top().first;
		int l=q.top().second.first;
		int r=q.top().second.second;
		q.pop();
		if(se.find({l,r})!=se.end())continue;
		se.insert({l,r});
		if(l==r)return -c;
		for(int i=-1;i<2;i++)for(int j=-1;j<2;j++)
			if(0<=l+i&&l+i<m && 0<=r+j&&r+j<m && fabs(my[l+i]-my[r+j])<1e-9)
				q.push({c-hypot(mx[l]-mx[l+i],my[l]-my[l+i])-hypot(mx[r]-mx[r+j],my[r]-my[r+j]),{l+i,r+j}});
	}
	abort();
}

int main(){
	int N,x,y;
	for(;scanf("%d",&N),N;){
		vector<pii>a(N);
		for(int i=0;i<N;i++)scanf("%d%d",&a[i].first,&a[i].second);
		printf("%f\n",solve(a));
	}
}

Compiler output:
a.cc: In function 'double solve(const std::vector<std::pair<int, int> >&)':
a.cc:60:62: error: 'fabs' was not declared in this scope; did you mean 'labs'?
   60 |                         if(0<=l+i&&l+i<m && 0<=r+j&&r+j<m && fabs(my[l+i]-my[r+j])<1e-9)
      |                                                              ^~~~
      |                                                              labs
a.cc:61:43: error: 'hypot' was not declared in this scope
   61 |                                 q.push({c-hypot(mx[l]-mx[l+i],my[l]-my[l+i])-hypot(mx[r]-mx[r+j],my[r]-my[r+j]),{l+i,r+j}});
      |                                           ^~~~~
a.cc:61:39: error: no matching function for call to 'std::priority_queue<std::pair<double, std::pair<int, int> > >::push(<brace-enclosed initializer list>)'
   61 |                                 q.push({c-hypot(mx[l]-mx[l+i],my[l]-my[l+i])-hypot(mx[r]-mx[r+j],my[r]-my[r+j]),{l+i,r+j}});
      |                                 ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/14/queue:66,
                 from a.cc:1:
/usr/include/c++/14/bits/stl_queue.h:736:7: note: candidate: 'void std::priority_queue<_Tp, _Sequence, _Compare>::push(const value_type&) [with _Tp = std::pair<double, std::pair<int, int> >; _Sequence = std::vector<std::pair<double, std::pair<int, int> >, std::allocator<std::pair<double, std::pair<int, int> > > >; _Compare = std::less<std::pair<double, std::pair<int, int> > >; value_type = std::pair<double, std::pair<int, int> >]'
  736 |       push(const value_type& __x)
      |       ^~~~
/usr/include/c++/14/bits/stl_queue.h:736:30: note:   no known conversion for argument 1 from '<brace-enclosed initializer list>' to 'const std::priority_queue<std::pair<double, std::pair<int, int> > >::value_type&' {aka 'const std::pair<double, std::pair<int, int> >&'}
  736 |       push(const value_type& __x)
      |            ~~~~~~~~~~~~~~~~~~^~~
/usr/include/c++/14/bits/stl_queue.h:744:7: note: candidate: 'void std::priority_queue<_Tp, _Sequence, _Compare>::push(value_type&&) [with _Tp = std::pair<double, std::pair<int, int> >; _Sequence = std::vector<std::pair<double, std::pair<int, int> >, std::allocator<std::pair<double, std::pair<int, int> > > >; _Compare = std::less<std::pair<double, std::pair<int, int> > >; value_type = std::pair<double, std::pair<int, int> >]'
  744 |       push(value_type&& __x)
      |       ^~~~
/usr/include/c++/14/bits/stl_queue.h:744:25: note:   no known conversion for argument 1 from '<brace-enclosed initializer list>' to 'std::priority_queue<std::pair<double, std::pair<int, int> > >::value_type&&' {aka 'std::pair<double, std::pair<int, int> >&&'}
  744 |       push(value_type&& __x)
      |            ~~~~~~~~~~~~~^~~