Language: C++

#include <iostream>
#include <queue>
using namespace std;

double memo[32][32]; //[vol][vertex] = time
int N,M,S,G;
struct e {
	int d,c;
}edge[32][32];

void solve(int vertex,int vol,int befor,double cost,int cnt)
{
	if(cost > memo[1][G])return;
	//printf("%d,%d,%d,%lf,%d\n",vertex,vol,befor,cost,cnt);
	
	int v;
	for(int i=1;i<=N;i++){
		if(vertex==i || i==befor || edge[vertex][i].d == 0)continue;
		if(vol>0 && vol<=edge[vertex][i].c){
			if(memo[vol][i] > (double)edge[vertex][i].d/(double)vol + cost){
				memo[vol][i] = (double)edge[vertex][i].d/(double)vol + cost;
				solve(i,vol,vertex,memo[vol][i],cnt+1);
			}
		}
		
		if(vol+1>0 && vol+1<=edge[vertex][i].c){
			if(memo[vol+1][i] > (double)edge[vertex][i].d/(double)(vol+1) + cost){
				memo[vol+1][i] = (double)edge[vertex][i].d/(double)(vol+1) + cost;
				solve(i,vol+1,vertex,memo[vol+1][i],cnt+1);
			}
		}
		
		if(vol-1>0 && vol-1<=edge[vertex][i].c){
			if(memo[vol-1][i] > (double)edge[vertex][i].d/(double)(vol-1) + cost){
				memo[vol-1][i] = (double)edge[vertex][i].d/(double)(vol-1) + cost;
				solve(i,vol-1,vertex,memo[vol-1][i],cnt+1);
			}
		}
	}
}

int main()
{
	int x,y,d,c;
	for(;cin>>N>>M,N||M;){
		cin>>S>>G;
		for(int i=0;i<32;i++)for(int j=0;j<32;j++)
			memo[i][j]=999999.0;
		memset(edge,0,sizeof(edge));
		for(int i=0;i<M;i++){
			cin>>x>>y>>d>>c;
			edge[x][y].d = edge[y][x].d = d;
			edge[x][y].c = edge[y][x].c = c;
		}
		memo[1][S] = 0.0;
		//solve(S, 0, 0, 0.0, 0);
		queue<pair<int,int> > qq;
		queue<int> befor;
		queue<double> cc;
		qq.push(make_pair(0,S));
		befor.push(S);
		cc.push(0.0);
		for(;!qq.empty();qq.pop()){
			int vol = qq.front().first;
			int vertex = qq.front().second;
			int b = befor.front();
			double cost = cc.front();
			befor.pop();
			cc.pop();
			for(int i=1;i<=N;i++){
				if(i==vertex || i==b || edge[vertex][i].d == 0)continue;
				if(vol>0 && vol<=edge[vertex][i].c){
					if(memo[vol][i] > (double)edge[vertex][i].d/vol + cost){
						memo[vol][i] = (double)edge[vertex][i].d/vol + cost;
						qq.push(make_pair(vol,i));
						befor.push(vertex);
						cc.push(memo[vol][i]);
						
					}
				}
				if(vol+1>0 && vol+1<=edge[vertex][i].c){
					if(memo[vol+1][i] > (double)edge[vertex][i].d/(vol+1) + cost){
						memo[vol+1][i] = (double)edge[vertex][i].d/(vol+1) + cost;
						qq.push(make_pair(vol+1,i));
						befor.push(vertex);
						cc.push(memo[vol+1][i]);
					}
				}
				if(vol-1>0 && vol-1<=edge[vertex][i].c){
					if(memo[vol-1][i] > (double)edge[vertex][i].d/(vol-1) + cost){
						memo[vol-1][i] = (double)edge[vertex][i].d/(vol-1) + cost;
						qq.push(make_pair(vol-1,i));
						befor.push(vertex);
						cc.push(memo[vol-1][i]);
					}
				}
			}
		}
		
		
		if(memo[1][G]==999999.0)
			puts("unreachable");
		else printf("%lf\n",memo[1][G]);
	}
	return 0;
}

Compiler output:
a.cc: In function 'int main()':
a.cc:49:17: error: 'memset' was not declared in this scope
   49 |                 memset(edge,0,sizeof(edge));
      |                 ^~~~~~
a.cc:3:1: note: 'memset' is defined in header '<cstring>'; this is probably fixable by adding '#include <cstring>'
    2 | #include <queue>
  +++ |+#include <cstring>
    3 | using namespace std;