Language: C++

#include<iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <stack>
#include <list>
#include <map>
#include <cmath>
#include <utility>
#include <cstdlib>
#include <cstring>
#include <string>
#include <set>
#include <climits>
#include <queue>
#include <stack>

using namespace std;

const double EPS (1e-8);
const double PI = acos(-1.0);

template<class T>
struct Po{
	T x,y;
	Po() : x(0),y(0) {}
	Po(const T &x,const T &y) : x(x),y(y) {}
	Po operator+(const Po& a) const { return P(x + a.x,y + a.y); }
	Po operator-(const Po& a) const { return P(x - a.x,y - a.y); }
	Po operator*(const double& a) const { return P(x * a, y * a); }
	Po operator/(const double& a) const { return P(x / a, y / a); }
};

enum{ CCW = 1,CW = -1,ON = 0};

typedef Po<double> P;

double SQ(double x) {return x* x; }
double abs(const P& a) { return sqrt(SQ(a.x) + SQ(a.y)); }
double dot( const P& a,const P &b){ return a.x * b.x + a.y * b.y ; }
double cross( const P& a,const P &b){ return a.x * b.y - a.y * b.x ; }

P rot(const P& a, double theta){
	return P( a.x * cos(theta) - a.y * sin(theta) ,
		a.x * sin(theta) + a.y * cos(theta) );
}

int ccw(P a,P b,P c){
	b = b - a; c = c - a;
	double rdir = cross(b,c);
	double len = abs(b) * abs(c);
	if( rdir > EPS *len) return CCW;
	else if( rdir < -EPS * len) return CW;
	return ON;
}

bool intersect(P& a1,P& b1,P& a2, P& b2){
	if(max(a1.x,b1.x) + EPS < min(a2.x,b2.x)
	||max(a1.y,b1.y) + EPS < min(a2.y,b2.y)
	||max(a2.x,b2.x) + EPS < min(a1.x,b1.x)
	||max(a2.y,b2.y) + EPS < min(a1.y,b1.y) ) return false;
	return ccw(a1,b1,a2) * ccw(a1,b1,b2) <= 0
		&& ccw(a2,b2,a1) * ccw(a2,b2,b1) <= 0;
}

typedef pair<P,P> PD;

PD GetContact(const P& p, const P &q,double pr,double pq){
	P a = q-p;
	P b = rot(a,PI / 2);
	double c = abs(a);
	b = b / c;

	double s = (pr + pq + c) / 2;
	double men = sqrt(s * (s - pr) * (s - pq) * (s - c));
	double l = 2 * men / c;
	double lp = sqrt(SQ(pr) - SQ(l));
	
	a = a / c * lp;
	b = b * l;
	return PD(p + a + b,p + a - b);
}

int n;
P p[100];
double r[100];
double dp[202][202];

#define FOR(i,n) for(int i = 0; i < (n) ; i++)


int main(){

	while(cin>>n,n){
		vector<P> us;
		vector<PD> vpd;
		FOR(i,n) cin>>p[i].x >> p[i].y >> r[i];
		FOR(i,202) FOR(j,202) dp[i][j] = 1e50;
		us.push_back(p[0]);

		for (int i = 0; i < n - 1; i++){
			PD pd = GetContact(p[i],p[i+1],r[i],r[i+1]);
			us.push_back(pd.first);
			us.push_back(pd.second);
			vpd.push_back(pd);
		}
		us.push_back(p[n-1]);

		for(int i = 0; i < (int)us.size(); i++){
			for(int j = i + 1; j < (int)us.size(); j++){
				bool ok = true;
				int l  = (1 + i) / 2;
				int r = (1 + j) / 2 - 1;
				for (int k = l; k < r; k++){
					if(!intersect(us[i],us[j],vpd[k].first,vpd[k].second))
						ok = false;
				}
				if(!ok) continue;
				double dist = abs(us[i] - us[j]);
				dp[j][i] = dp[i][j] = dist;
			}
		}

		int a = (int)us.size();
		FOR(k,a) FOR(i,a) FOR(j,a) dp[i][j] = min(dp[i][j],dp[i][k] + dp[k][j]);

		printf("%.10lf\n",dp[0][a - 1]);

	}
	return 0;
}

Compiler output:
a.cc: In instantiation of 'Po<T> Po<T>::operator-(const Po<T>&) const [with T = double]':
a.cc:49:10:   required from here
   49 |         b = b - a; c = c - a;
      |                 ^
a.cc:29:51: error: expected primary-expression
   29 |         Po operator-(const Po& a) const { return P(x - a.x,y - a.y); }
      |                                                  ~^~~~~~~~~~~~~~~~~
a.cc: In instantiation of 'Po<T> Po<T>::operator/(const double&) const [with T = double]':
a.cc:72:10:   required from here
   72 |         b = b / c;
      |                 ^
a.cc:31:55: error: expected primary-expression
   31 |         Po operator/(const double& a) const { return P(x / a, y / a); }
      |                                                      ~^~~~~~~~~~~~~~
a.cc: In instantiation of 'Po<T> Po<T>::operator*(const double&) const [with T = double]':
a.cc:79:14:   required from here
   79 |         a = a / c * lp;
      |                     ^~
a.cc:30:55: error: expected primary-expression
   30 |         Po operator*(const double& a) const { return P(x * a, y * a); }
      |                                                      ~^~~~~~~~~~~~~~
a.cc: In instantiation of 'Po<T> Po<T>::operator+(const Po<T>&) const [with T = double]':
a.cc:81:16:   required from here
   81 |         return PD(p + a + b,p + a - b);
      |                       ^
a.cc:28:51: error: expected primary-expression
   28 |         Po operator+(const Po& a) const { return P(x + a.x,y + a.y); }
      |                                                  ~^~~~~~~~~~~~~~~~~