Problem:
Problem D:
Traveling by Stagecoach
Once upon a time, there was a traveler.
He plans to travel using stagecoaches (horse wagons).
His starting point and destination are fixed,
but he cannot determine his route.
Your job in this problem is to write a program
which determines the route for him.
There are several cities in the country,
and a road network connecting them.
If there is a road between two cities, one can travel by a stagecoach
from one of them to the other.
A coach ticket is needed for a coach ride.
The number of horses is specified in each of the tickets.
Of course, with more horses, the coach runs faster.
At the starting point, the traveler has a number of coach tickets.
By considering these tickets and the information on the road network,
you should find the best possible route that takes him to the destination
in the shortest time.
The usage of coach tickets should be taken into account.
The following conditions are assumed.
A coach ride takes the traveler from one city to another 
directly connected by a road.
In other words, on each arrival to a city, he must change the coach.
Only one ticket can be used for a coach ride between two cities
directly connected by a road.
Each ticket can be used only once.
The time needed for a coach ride is the distance between two cities
divided by the number of horses.
The time needed for the coach change should be ignored.
Input
The input consists of multiple datasets, each in the following format.
The last dataset is followed by a line containing five zeros
(separated by a space).
n m p a b
t
1
t
2
...
t
n
x
1
y
1
z
1
x
2
y
2
z
2
...
x
p
y
p
z
p
Every input item in a dataset is a non-negative integer.
If a line contains two or more input items, they are separated by a space.
n
is the number of coach tickets.
You can assume that the number of tickets is between 1 and 8.
m
is the number of cities in the network.
You can assume that the number of cities is between 2 and 30.
p
is the number of roads between cities, which may be zero.
a
is the city index of the starting city.
b
is the city index of the destination city.
a
is not equal to
b
.
You can assume that all city indices in a dataset (including the above two)
are between 1 and
m
.
The second line of a dataset gives the details of coach tickets.
t
i
is the number of horses specified in the
i
-th
coach ticket (1<=
i
<=
n
).
You can assume that the number of horses is between 1 and 10.
The following
p
lines give the details of roads between cities.
The
i
-th road connects two cities with city indices
x
i
and
y
i
,
and has a distance
z
i
(1<=
i
<=
p
).
You can assume that the distance is between 1 and 100.
No two roads connect the same pair of cities.
A road never connects a city with itself.
Each road can be traveled in both directions.
Output
For each dataset in the input, one line should be output as specified below.
An output line should not contain extra characters such as spaces.
If the traveler can reach the destination, the time needed
for 
...(truncated)

Submitted solutions:

code_snippet: #include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

const int INF = 0x3f3f3f3f;
const int MAX_N = 8;
const int MAX_M = 30;

int N, M, P, A, B;

int t[MAX_N];
int w[MAX_M][MAX_M];
double dp[(1 << MAX_N)][MAX_M];
// dp[S][v]: 从A到v的最小时间
//  S  用掉的车票数
//  v  相邻的城市

int main() 
{
	while (scanf("%d %d %d %d %d", &N, &M, &P, &A, &B))
	{
		if (N == 0 && M == 0 && P == 0 && A == 0 && B == 0) break;

		A--; B--;

		// 初始化
		memset(w, INF, sizeof(w));
		for (int v = 0; v < M; v++)
		{
			w[v][v] = 0;
		}
		for (int s = 0; s < (1 << N); s++) 
		{
			for (int v = 0; v < M; v++)
			{
				dp[s][v] = INF;
			}
		}

		// 输入
		for (int i = 0; i < N; i++) //马车的马个数
		{
			scanf("%d", &t[i]);
		}

		for (int u = 0; u < M; u++) 
		{
			fill(w[u], w[u] + M, INF);
			w[u][u] = 0;
		}

		for (int i = 0; i < P; i++) //输入网络
		{
			int u, v, d;
			scanf("%d %d %d", &u, &v, &d);
			u--; v--;
			w[u][v] = w[v][u] = d;
		}

		dp[0][A] = 0;

		for (int S = 1; S < (1 << N); S++) 
		{
			for (int v = 0; v < M; v++)
			{
				for (int u = 0; u < M; u++) 
				{ // from u
					if (w[u][v] == INF) continue; // no edge between u -> v

					for (int x = 0; x < N; x++)
					{ 
						// use ticket x
						if (!(S & (1 << x))) continue; // ticket x not in S

						dp[S][v] = min(dp[S][v],dp[S ^ (1 << x)][u] + double(w[u][v]) / t[x]);
					}
				}
			}
		}

		double ans = INF;
		for (int S = 0; S < (1 << N); S++) 
		{
			ans = min(ans, dp[S][B]);
		}

		if (fabs(ans - INF) < 1e-8) puts("Impossible");
		else 
		{
			printf("%.10f\n", ans);
		}

	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3564
final_rank: 3

code_snippet: #include<iostream>
#include<vector>
#include<queue>
#include<iomanip>
using namespace std;
using Vertex=pair<double,pair<int,int> >;
int T,N,M,a,b;
double t[8];
vector<pair<int,double> >G[31];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	while(1)
	{
		cin>>T>>N>>M>>a>>b;
		if(T==0)break;
		a--,b--;
		for(int i=0;i<T;i++)cin>>t[i];
		for(int i=0;i<N;i++)G[i].clear();
		for(int i=0;i<M;i++)
		{
			int u,v,w;cin>>u>>v>>w;
			u--,v--;
			G[u].push_back(make_pair(v,w));
			G[v].push_back(make_pair(u,w));
		}
		priority_queue<Vertex,vector<Vertex>,greater<Vertex> >Q;
		Q.push(make_pair(0,make_pair(a,0)));
		vector<vector<double> >dist(N,vector<double>(1<<T,1e9));
		dist[a][0]=0;
		while(!Q.empty())
		{
			auto[d,tmp]=Q.top();Q.pop();
			auto[u,used]=tmp;
			if(u==b)continue;
			if(dist[u][used]<d)continue;
			for(auto[v,c]:G[u])for(int i=0;i<T;i++)if(!(used>>i&1))
			{
				double nd=d+c/t[i];
				int nused=used|(1<<i);
				if(dist[v][nused]<=nd)continue;
				dist[v][nused]=nd;
				Q.push(make_pair(nd,make_pair(v,nused)));
			}
		}
		double ans=1e9;
		for(int i=0;i<1<<T;i++)ans=min(ans,dist[b][i]);
		if(ans==1e9)cout<<"Impossible"<<endl;
		else cout<<fixed<<setprecision(10)<<ans<<endl;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 5308
final_rank: 9

code_snippet: #include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#include<iomanip>
using namespace std;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	while(1)
	{
		int N,M,p,a,b;cin>>N>>M>>p>>a>>b;
		if(N==0)break;
		vector<double>t(N);
		for(int i=0;i<N;i++)cin>>t[i];
		vector<vector<pair<int,double> > >G(M+1,vector<pair<int,double> >());
		for(int i=0;i<p;i++)
		{
			int x,y,z;cin>>x>>y>>z;
			G[x].push_back(make_pair(y,z));
			G[y].push_back(make_pair(x,z));
		}
		vector<vector<double>>dist(M+1,vector<double>(1<<N,1e9));
		dist[a][0]=0;
		priority_queue<pair<double,pair<int,int> >,vector<pair<double,pair<int,int> > >,greater<pair<double,pair<int,int> > > >Q;
		Q.push(make_pair(0,make_pair(a,0)));
		while(!Q.empty())
		{
			auto[d,p]=Q.top();Q.pop();
			auto[u,used]=p;
			if(u==b)continue;
			if(dist[u][used]<d)continue;
			for(auto[v,c]:G[u])for(int i=0;i<N;i++)
			{
				if(used>>i&1)continue;
				double nd=d+c/t[i];
				int nxt=used|(1<<i);
				if(dist[v][nxt]<=nd)continue;
				dist[v][nxt]=nd;
				Q.push(make_pair(nd,make_pair(v,nxt)));
			}
		}
		double ans=1e9;
		for(int i=0;i<1<<N;i++)ans=min(ans,dist[b][i]);
		if(ans==1e9)cout<<"Impossible"<<endl;
		else cout<<fixed<<setprecision(10)<<ans<<endl;
	}
}
accuracy: 1
time_ms: 30
memory_kb: 5312
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

using edge       = pair<int, double>;
const double INF = 2e9;

int main() {
    while (true) {
        int n, m, p, s, t;
        cin >> n >> m >> p >> s >> t;
        if (n == 0 && m == 0 && p == 0 && s == 0 && t == 0) {
            break;
        }
        s--;
        t--;

        vector<int> T(n);
        for (int i = 0; i < n; i++) {
            cin >> T[i];
        }
        vector<vector<edge>> E(m);
        for (int i = 0; i < p; i++) {
            int x, y;
            double z;
            cin >> x >> y >> z;
            x--;
            y--;
            E[x].emplace_back(y, z);
            E[y].emplace_back(x, z);
        }

        vector<vector<double>> dist(m, vector<double>(1 << n, INF));
        priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;
        dist[s][0] = 0;
        pq.emplace(0, s, 0);
        while (!pq.empty()) {
            auto [cost, u, bit] = pq.top();
            pq.pop();
            if (dist[u][bit] < cost) {
                continue;
            }
            for (auto [v, w] : E[u]) {
                for (int i = 0; i < n; i++) {
                    if (bit & (1 << i)) {
                        continue;
                    }
                    int next_bit     = bit | (1 << i);
                    double next_cost = cost + w / T[i];
                    if (dist[v][next_bit] > next_cost) {
                        dist[v][next_bit] = next_cost;
                        pq.emplace(next_cost, v, next_bit);
                    }
                }
            }
        }

        double ans = INF;
        for (int bit = 0; bit < (1 << n); bit++) {
            ans = min(ans, dist[t][bit]);
        }
        if (ans == INF) {
            cout << "Impossible" << endl;
        } else {
            printf("%.10f\n", ans);
        }
    }
}
accuracy: 1
time_ms: 30
memory_kb: 5288
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

using edge       = pair<int, double>;
const double INF = 2e9;

int main() {
    while (true) {
        int n, m, p, s, t;
        cin >> n >> m >> p >> s >> t;
        if (n == 0 && m == 0 && p == 0 && s == 0 && t == 0) {
            break;
        }
        s--;
        t--;

        vector<int> T(n);
        for (int i = 0; i < n; i++) {
            cin >> T[i];
        }
        vector<vector<edge>> E(m);
        for (int i = 0; i < p; i++) {
            int x, y;
            double z;
            cin >> x >> y >> z;
            x--;
            y--;
            E[x].emplace_back(y, z);
            E[y].emplace_back(x, z);
        }

        vector<vector<double>> dist(m, vector<double>(1 << n, INF));
        priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;
        dist[s][0] = 0;
        pq.emplace(0, s, 0);
        while (!pq.empty()) {
            auto [cost, u, bit] = pq.top();
            pq.pop();
            if (dist[u][bit] < cost) {
                continue;
            }
            for (auto [v, w] : E[u]) {
                for (int i = 0; i < n; i++) {
                    if (bit & (1 << i)) {
                        continue;
                    }
                    int next_bit     = bit | (1 << i);
                    double next_cost = dist[u][bit] + w / T[i];
                    if (dist[v][next_bit] > next_cost) {
                        dist[v][next_bit] = next_cost;
                        pq.emplace(next_cost, v, next_bit);
                    }
                }
            }
        }

        double ans = INF;
        for (int bit = 0; bit < (1 << n); bit++) {
            ans = min(ans, dist[t][bit]);
        }
        if (ans == INF) {
            cout << "Impossible" << endl;
        } else {
            printf("%.10f\n", ans);
        }
    }
}
accuracy: 1
time_ms: 30
memory_kb: 5292
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  while(true) {
    ll C, N, M, S, T;
    cin >> C >> N >> M >> S >> T;
    S--, T--;

    if(!C) { break; }

    vector<double> t(C);
    for(auto &i : t) { cin >> i; }

    vector<vector<pair<ll, double>>> g(N);
    for(ll i = 0, u, v, w; i < M; i++) {
      cin >> u >> v >> w;
      u--, v--;
      g[u].emplace_back(v, w);
      g[v].emplace_back(u, w);
    }

    vector<vector<double>> dp(N, vector<double>(1 << C, 1e18));
    dp[S][0] = 0;
    priority_queue<tuple<double, ll, ll>, vector<tuple<double, ll, ll>>, greater<tuple<double, ll, ll>>> q;
    q.emplace(0, S, 0);

    while(!q.empty()) {
      auto [d, v, s] = q.top();
      q.pop();
      if(dp[v][s] < d) { continue; }
      for(auto &[nv, w] : g[v]) {
        for(ll i = 0; i < C; i++) {
          if(s >> i & 1) { continue; }
          ll ns = s | (1 << i);
          double nd = d + w / t[i];
          if(nd < dp[nv][ns]) {
            dp[nv][ns] = nd;
            q.emplace(nd, nv, ns);
          }
        }
      }
    }

    double ans = ranges::min(dp[T]);
    if(ans > 1e17) { cout << "Impossible\n"; }
    else { cout << fixed << setprecision(12) << ans << "\n"; }
  }
}
accuracy: 1
time_ms: 30
memory_kb: 6080
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef long double ld;
typedef pair<ll,ll> pi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(A) A.begin(),A.end()
template<typename T>bool chmin(T&a,T b){if(a>b){a=b;return 1;}return 0;}
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
int main(){
    while(1){
        ll T,N,M,s,g;
        cin>>T>>N>>M>>s>>g;s--;g--;
        if(!T)return 0;
        vi A(T);REP(i,T)cin>>A[i];//頭数
        vector<vector<pi>>E(N);
        REP(i,M){
            ll u,v,d;cin>>u>>v>>d;u--;v--;
            E[u].emplace_back(pi(v,d));
            E[v].emplace_back(pi(u,d));
        }
        vector<vector<ld>>D(N,vector<ld>(1<<T,1e18));
        D[s].back()=0;
        min_priority_queue<pair<ld,pi>>Q;
        Q.emplace(make_pair(0,pi(s,(1<<T)-1)));
        while(!Q.empty()){
            auto[d,p]=Q.top();Q.pop();
            if(d!=D[p.first][p.second])continue;
            for(auto[u,c]:E[p.first])REP(i,T)if((p.second>>i)%2){
                if(chmin(D[u][p.second-(1<<i)],d+(ld)c/A[i])){
                    Q.emplace(make_pair(d+(ld)c/A[i],pi(u,p.second-(1<<i))));
                }
            }
        }
        ld ans=*min_element(ALL(D[g]));
        if(ans>1e17)cout<<"Impossible"<<endl;
        else printf("%.20Lf\n",ans);
    }
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 6300
final_rank: 13

code_snippet: #include <iostream>
#include <vector>
using namespace std;

int main() {
    int n, m, p, a, b;
    while (true) {
        cin >> n >> m >> p >> a >> b;
        if (n == 0 && m == 0 && p == 0 && a == 0 && b == 0) {
            break;
        }
        vector<int> t(n);
        for (int i = 0; i < n; i++) {
            cin >> t[i];
        }
        a--, b--;
        vector<vector<pair<int, double> > > g(m);
        for (int i = 0; i < p; i++) {
            int x, y, z;
            cin >> x >> y >> z;
            x--, y--;
            pair<int, double> p1;
            p1.first = y, p1.second = z;
            pair<int, double> p2;;
            p2.first = x, p2.second = z;
            g[x].push_back(p1);
            g[y].push_back(p2);
        }
        vector<vector<double> > dp((1 << n), vector<double>(m, 1e18));
        dp[0][a] = 0;
        for (int mask = 0; mask < (1 << n); mask++) {
            for (int v = 0; v < m; v++) {
                for (int i = 0; i < n; i++) {
                    if ((mask >> i) & 1) {
                        continue;
                    }
                    for (int k = 0; k < g[v].size(); k++) {
                        int u = g[v][k].first;
                        double w = g[v][k].second;
                        dp[mask | (1 << i)][u] = min(dp[mask | (1 << i)][u], dp[mask][v] + (w / t[i]));
                    }
                }
            }
        }
        double ans = 1e18;
        for (int mask = 0; mask < (1 << n); mask++) {
            ans = min(ans, dp[mask][b]);
        }
        if (ans == 1e18) {
            cout << "Impossible" << '\n';
        } else {
            cout << ans << '\n';
        }
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3308
final_rank: 1

code_snippet: #include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_set>
#include <vector>

using namespace std;
using ll = long long;

struct Node {
	int city;
	int tickets;

	Node(const int city, const int tickets)
		: city(city), tickets(tickets) {};

	bool operator<(const Node& node) const {
		if (this->city != node.city) return this->city < node.city;
		else return this->tickets < node.tickets;
	}
};

struct QueueItem {
	Node node;
	double shortest_time;

	QueueItem(const Node node, const double shortest_time)
		: node(node), shortest_time(shortest_time) {};

	bool operator<(const QueueItem& queue_item) const {
		return this->shortest_time > queue_item.shortest_time;
	}
};

void Solve(const int& n, const int& dep, const int& dst, const map<int, int>& numof_horses, const vector<map<int, int>>& distances) {
	double shortest_time_to_dst = -1.0;

	map<Node, double> shortest_time;
	priority_queue<QueueItem> queue;

	shortest_time[Node(dep, (1 << n) - 1)] = 0.0;
	queue.push(QueueItem((*shortest_time.begin()).first, (*shortest_time.begin()).second));
	while (!queue.empty()) {
		Node current = queue.top().node;
		queue.pop();

		if (current.city == dst) {
			shortest_time_to_dst = shortest_time[current];
			break;
		}

		for (const auto& entry : distances[current.city]) {
			int adjacent_city = entry.first, distance = entry.second;
			for (int ticket = 1 << (n - 1); ticket > 0; ticket >>= 1) {
				if ((current.tickets & ticket) == 0) continue;
				Node adjacent(adjacent_city, current.tickets ^ ticket);
				double adjacent_shortest_time = shortest_time[current] + (double)distance / numof_horses.at(ticket);
				if (shortest_time.find(adjacent) != shortest_time.end() and shortest_time[adjacent] <= adjacent_shortest_time) continue;
				shortest_time[adjacent] = adjacent_shortest_time;
				queue.push(QueueItem(adjacent, adjacent_shortest_time));
			}
		}
	}

	if (shortest_time_to_dst == -1.0) cout << "Impossible" << endl;
	else cout << shortest_time_to_dst << endl;
}

int main(void) {
	cout << fixed << setprecision(3);
	while (true) {
		int n, m, p, a, b;
		cin >> n >> m >> p >> a >> b;
		if (n == 0) break;
		a--;
		b--;
		map<int, int> numof_horses;
		for (int ticket = 1 << (n - 1); ticket > 0; ticket >>= 1) cin >> numof_horses[ticket];
		vector<map<int, int>> distances(m);
		for (int i = 0; i < p; i++) {
			int x, y, z;
			cin >> x >> y >> z;
			x--;
			y--;
			distances[x][y] = distances[y][x] = z;
		}
		Solve(n, a, b, numof_horses, distances);
	}
	return 0;
}
accuracy: 1
time_ms: 630
memory_kb: 5100
final_rank: 15

code_snippet: #include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_set>
#include <vector>

using namespace std;
using ll = long long;

struct Node {
	int city;
	int tickets;

	Node(const int city, const int tickets)
		: city(city), tickets(tickets) {};

	bool operator<(const Node& node) const {
		if (this->city != node.city) return this->city < node.city;
		else return this->tickets < node.tickets;
	}
};

struct QueueItem {
	Node node;
	double shortest_time;

	QueueItem(const Node node, const double shortest_time)
		: node(node), shortest_time(shortest_time) {};

	bool operator<(const QueueItem& queue_item) const {
		return this->shortest_time > queue_item.shortest_time;
	}
};

void Solve(const int& n, const int& dep, const int& dst, const map<int, int>& numof_horses, const vector<map<int, int>>& distances) {
	double shortest_time_to_dst = -1.0;

	map<Node, double> shortest_time;
	priority_queue<QueueItem> queue;

	shortest_time[Node(dep, (1 << n) - 1)] = 0.0;
	queue.push(QueueItem((*shortest_time.begin()).first, (*shortest_time.begin()).second));
	while (!queue.empty()) {
		Node current = queue.top().node;
		queue.pop();

		if (current.city == dst) {
			shortest_time_to_dst = shortest_time[current];
			break;
		}

		if (current.tickets == 0) continue;

		for (const auto& entry : distances[current.city]) {
			int adjacent_city = entry.first, distance = entry.second;
			for (int ticket = 1 << (n - 1); ticket > 0; ticket >>= 1) {
				if ((current.tickets & ticket) == 0) continue;
				Node adjacent(adjacent_city, current.tickets ^ ticket);
				double adjacent_shortest_time = shortest_time[current] + (double)distance / numof_horses.at(ticket);
				if (shortest_time.find(adjacent) != shortest_time.end() and shortest_time[adjacent] <= adjacent_shortest_time) continue;
				shortest_time[adjacent] = adjacent_shortest_time;
				queue.push(QueueItem(adjacent, adjacent_shortest_time));
			}
		}
	}

	if (shortest_time_to_dst == -1.0) cout << "Impossible" << endl;
	else cout << shortest_time_to_dst << endl;
}

int main(void) {
	cout << fixed << setprecision(3);
	while (true) {
		int n, m, p, a, b;
		cin >> n >> m >> p >> a >> b;
		if (n == 0) break;
		a--;
		b--;
		map<int, int> numof_horses;
		for (int ticket = 1 << (n - 1); ticket > 0; ticket >>= 1) cin >> numof_horses[ticket];
		vector<map<int, int>> distances(m);
		for (int i = 0; i < p; i++) {
			int x, y, z;
			cin >> x >> y >> z;
			x--;
			y--;
			distances[x][y] = distances[y][x] = z;
		}
		Solve(n, a, b, numof_horses, distances);
	}
	return 0;
}
accuracy: 1
time_ms: 720
memory_kb: 5232
final_rank: 16

code_snippet: #include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_set>
#include <vector>

using namespace std;
using ll = long long;

struct Node {
	int city;
	int tickets;

	Node(const int city, const int tickets)
		: city(city), tickets(tickets) {};

	bool operator<(const Node& node) const {
		if (this->city != node.city) return this->city < node.city;
		else return this->tickets < node.tickets;
	}
};

struct QueueItem {
	Node node;
	double shortest_time;

	QueueItem(const Node node, const double shortest_time)
		: node(node), shortest_time(shortest_time) {};

	bool operator<(const QueueItem& queue_item) const {
		return this->shortest_time > queue_item.shortest_time;
	}
};

void Solve(const int& n, const int& dep, const int& dst, const map<int, int>& numof_horses, const vector<map<int, int>>& distances) {
	double shortest_time_to_dst = -1.0;

	map<Node, double> shortest_time;
	map<Node, bool> done;
	priority_queue<QueueItem> queue;

	shortest_time[Node(dep, (1 << n) - 1)] = 0.0;
	queue.push(QueueItem((*shortest_time.begin()).first, (*shortest_time.begin()).second));
	while (!queue.empty()) {
		Node current = queue.top().node;
		queue.pop();

		if (current.city == dst) {
			shortest_time_to_dst = shortest_time[current];
			break;
		}

		if (done[current]) continue;
		done[current] = true;

		if (current.tickets == 0) continue;

		for (const auto& entry : distances[current.city]) {
			int adjacent_city = entry.first, distance = entry.second;
			for (int ticket = 1 << (n - 1); ticket > 0; ticket >>= 1) {
				if ((current.tickets & ticket) == 0) continue;
				Node adjacent(adjacent_city, current.tickets ^ ticket);
				if (done[adjacent]) continue;
				double adjacent_shortest_time = shortest_time[current] + (double)distance / numof_horses.at(ticket);
				if (shortest_time.find(adjacent) != shortest_time.end() and shortest_time[adjacent] <= adjacent_shortest_time) continue;
				shortest_time[adjacent] = adjacent_shortest_time;
				queue.push(QueueItem(adjacent, adjacent_shortest_time));
			}
		}
	}

	if (shortest_time_to_dst == -1.0) cout << "Impossible" << endl;
	else cout << shortest_time_to_dst << endl;
}

int main(void) {
	cout << fixed << setprecision(3);
	while (true) {
		int n, m, p, a, b;
		cin >> n >> m >> p >> a >> b;
		if (n == 0) break;
		a--;
		b--;
		map<int, int> numof_horses;
		for (int ticket = 1 << (n - 1); ticket > 0; ticket >>= 1) cin >> numof_horses[ticket];
		vector<map<int, int>> distances(m);
		for (int i = 0; i < p; i++) {
			int x, y, z;
			cin >> x >> y >> z;
			x--;
			y--;
			distances[x][y] = distances[y][x] = z;
		}
		Solve(n, a, b, numof_horses, distances);
	}
	return 0;
}
accuracy: 1
time_ms: 540
memory_kb: 5404
final_rank: 14

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

ll LCM = 2520;

int main() {
while(1) {
    int N, M, L, S, T;
    cin >> L >> N >> M >> S >> T;
    if (N == 0) return 0;
    S--, T--;
    vector<ll> A(L);
    rep(i,0,L) cin >> A[i], A[i] = LCM / A[i];
    vector<vector<pair<int,ll>>> G(N);
    rep(i,0,M) {
        int X, Y;
        ll Z;
        cin >> X >> Y >> Z;
        X--, Y--;
        G[X].push_back({Y,Z});
        G[Y].push_back({X,Z});
    }
    int K = 1<<L;
    vector<vector<ll>> DP(N, vector<ll>(K,INF));
    priority_queue<pair<ll,pair<int,int>>, vector<pair<ll,pair<int,int>>>, greater<pair<ll,pair<int,int>>>> Q;
    DP[S][0] = 0;
    Q.push({0,{S,0}});
    while(!Q.empty()) {
        auto [D, P] = Q.top();
        auto [X, Y] = P;
        Q.pop();
        if (D > DP[X][Y]) continue;
        rep(i,0,L) {
            if ((Y & (1<<i)) != 0) continue;
            for (auto [NX, ND] : G[X]) {
                int NY = Y | (1<<i);
                ll NND = D + ND * A[i];
                if (NND < DP[NX][NY]) {
                    DP[NX][NY] = NND;
                    Q.push({NND,{NX,NY}});
                }
            }
        }
    }
    ll ANS = INF;
    rep(i,0,K) {
        chmin(ANS, DP[T][i]);
    }
    if (ANS == INF) print("Impossible");
    else print((double)ANS / (double)LCM);
}
}
accuracy: 1
time_ms: 20
memory_kb: 4940
final_rank: 5

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
using ll = long long;
#define MOD 1000000007
#define Mod 998244353
const int MAX = 1000000005;
const long long INF = 1000000000000000005LL;
using namespace std;
//using namespace atcoder;

using d_i = pair<double, int>;
const double eps = 1e-6;

bool solve() {
    int n, m, p, a, b;
    cin >> n >> m >> p >> a >> b;
    a--; b--;
    if (n == 0) return false;
    vector<int> t(n);
    for (int i = 0; i < n; i++) cin >> t[i];
    vector<vector<pair<int, int>>> G(m);
    for (int i = 0; i < p; i++) {
        int x, y, z;
        cin >> x >> y >> z;
        x--; y--;
        G[x].push_back({y, z});
        G[y].push_back({x, z});
    }
    vector<int> vec(n);
    for (int i = 0; i < n; i++) vec[i] = i;
    double ans = 1e+10;
    do {
        vector<vector<double>> dp(n+1, vector<double>(m, 1e+10));
        dp[0][a] = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                for (auto [k, cost] : G[j]) {
                    dp[i+1][k] = min(dp[i+1][k], dp[i][j] + (double)cost/t[vec[i]]);
                }
            }
            ans = min(ans, dp[i+1][b]);
        }
    } while (next_permutation(vec.begin(), vec.end()));
    if (fabs(ans - 1e+10) <= eps) cout << "Impossible" << endl;
    else cout << fixed << setprecision(10) << ans << endl;
    return true;
}

int main() {
    ios::sync_with_stdio(0); cin.tie();
    while (solve()) {}
}
accuracy: 1
time_ms: 1480
memory_kb: 3356
final_rank: 19

code_snippet: #include<bits/stdc++.h>
//#include <atcoder/all>
using namespace std;
//using namespace atcoder;

#define all(v) v.begin(),v.end()
using ll = long long;
using ull = unsigned long long;
using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<ll,ll>;
using PP=pair<double,P>;
using vp=vector<pair<ll, ll>>;
//using mint=modint1000000007;
//using mint=modint998244353;

const ll INF=1ll<<60;
ll mod10=1e9+7;
ll mod99=998244353;
const double PI = acos(-1);

#define rep(i,n) for (ll i=0;i<n;++i)
#define per(i,n) for(ll i=n-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=a;i<n;++i)
#define per2(i,a,n) for (ll i=a;i>=n;--i)

template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }

bool solve(){
    ll N,M,P,a,b;cin>>N>>M>>P>>a>>b;
    if(N==0&&M==0&&P==0) return 0;
    a--;b--;
    vll T(N);rep(i,N)cin>>T[i];
    vector<vp> ab(M);
    rep(i,P){
        ll x,y,c;cin>>x>>y>>c;
        x--;y--;
        ab[x].push_back({c,y});
        ab[y].push_back({c,x});
    }

    vector dist(M,vector<double>(1<<N,INF));
    
    priority_queue<PP,vector<PP>,greater<PP>> pq;
    pq.push({0,{a,0}});
    while(pq.size()){
        auto [t,now1]=pq.top();pq.pop();
        auto [now,bit]=now1;
        if(dist[now][bit]!=INF) continue;
        dist[now][bit]=t;
        for(auto [c,to]:ab[now]){
            rep(j,N){
                if(bit>>j&1) continue;
                double nt=t+(double)c/T[j];
                
                pq.push({nt,{to,bit|(1<<j)}});
            }
        }
    }

    double ans=INF;
    rep(i,(1<<N)) chmin(ans,dist[b][i]);
    if(ans==INF) cout << "Impossible" << endl;
    else cout << ans << endl;
    
    return 1;
}



int main(){
   cin.tie(0);
   ios::sync_with_stdio(false);
   while(solve());
}
accuracy: 1
time_ms: 710
memory_kb: 28040
final_rank: 20

code_snippet: #include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < n; i++)
using namespace std;
using i_i = pair<int, int>;

bool solve() {
    int n, m, p, a, b; cin >> n >> m >> p >> a >> b;
    if (n == 0) return false;
    a--, b--;
    vector<int> t(n); rep(i, n) cin >> t[i];
    vector to(m, vector<i_i>());
    for (int i = 0; i < p; i++) {
        int x, y, z; cin >> x >> y >> z;
        x--, y--;
        to[x].emplace_back(y, z);
        to[y].emplace_back(x, z);
    }
    int k = 1 << n;
    int INF = 1001001001;
    vector dp(m, vector<double>(k, INF));
    using S = tuple<double, int, int>;
    priority_queue<S, vector<S>, greater<S>> pq;
    pq.emplace(0, a, 0);
    dp[a][0] = 0;
    while (pq.size()) {
        auto [c, v, bit] = pq.top(); pq.pop();
        if (dp[v][bit] != c) continue;
        for (auto [u, dc] : to[v]) {
            rep(i, n) if (~bit >> i & 1) {
                int nbit = bit | (1 << i);
                double nc = c + (double)dc / t[i];
                assert(u < m and nbit < k);
                if (dp[u][nbit] <= nc) continue;
                dp[u][nbit] = nc;
                pq.emplace(nc, u, nbit);
            }
        }
    }
    double ans = INF;
    for (int i = 0; i < k; i++) {
        assert(b < dp.size());
        assert(i < dp[b].size());
        if (ans > dp[b][i]) ans = dp[b][i];
    }
    if (ans == INF) {
        cout << "Impossible" << endl;
    } else {
        cout << fixed << setprecision(6) << ans << endl;
    }
    return true;
}

int main() {
    while (solve());
}
accuracy: 1
time_ms: 40
memory_kb: 4880
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
int n,m,p,a,b,t[10];
vector<pair<int,int>>g[30];
void solve(){
  vector<vector<double>>dist(m,vector<double>(1<<n,1.0e18));
  dist[a][0]=0.0;
  priority_queue<tuple<double,int,int>,vector<tuple<double,int,int>>,greater<>>que;
  que.push({dist[a][0],a,0});
  while(!que.empty()){
    auto[d,v,bit]=que.top();
    que.pop();
    for(auto[vv,dd]:g[v]){
      for(int i=0;i<n;++i){
        if(bit&(1<<i))continue;
        double nd=dist[v][bit]+(double)dd/t[i];
        if(nd<dist[vv][bit|(1<<i)]){
          dist[vv][bit|(1<<i)]=nd;
          que.push({nd,vv,bit|(1<<i)});
        }
      }
    }
  }
  double ans=1.0e18;
  for(int bit=0;bit<1<<n;++bit)ans=min(ans,dist[b][bit]);
  if(5.0e17<ans){
    cout<<"Impossible"<<'\n';
    return;
  }
  cout<<ans<<'\n';
}
int main(){
  cin.tie(0)->sync_with_stdio(0);
  cout<<fixed<<setprecision(20);
  while(1){
    cin>>n>>m>>p>>a>>b,--a,--b;
    if(n==0)break;
    for(int i=0;i<n;++i)cin>>t[i];
    for(int i=0;i<m;++i)g[i].clear();
    for(int i=0;i<p;++i){
      int x,y,z;cin>>x>>y>>z,--x,--y;
      g[x].emplace_back(y,z);
      g[y].emplace_back(x,z);
    }
    solve();
  }
}
accuracy: 1
time_ms: 60
memory_kb: 4892
final_rank: 11

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = 3.141592653589793;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

tuple<vc<double>, vi> dijkstra(int s, int N, vv<pair<int, double>> &g){
    using P = pair<double, int>;
    vc<double> dist(N, inf);
    vi bef(N);
    priority_queue<P, vc<P>, greater<P>> q;
    dist[s] = 0;
    q.push({0, s});
    while (!q.empty()){
        auto [c, now] = q.top();q.pop();
        if (dist[now] < c) continue;
        for (auto&& [nxt, nc]: g[now]) if (dist[nxt] > c + nc){
            dist[nxt] = c + nc;
            bef[nxt] = now;
            q.push({dist[nxt], nxt}); 
        }
    }
    return {dist, bef};
}

double solve(int N, int M, int P, int a, int b){
    vi T(N); rep(i, N) cin >> T[i];
    int K = (1 << N);
    vv<pair<int, double>> g(M * K);
    rep(_, P){
        int x, y, z; cin >> x >> y >> z;x--; y--;
        rep(cmb, 1 << N) rep(i, N) if (~cmb >> i & 1){
            g[x * K + (cmb | (1 << i))].push_back({y * K + cmb, z / (double)T[i]});
            g[y * K + (cmb | (1 << i))].push_back({x * K + cmb, z / (double)T[i]});
        }
    }
    auto [dist, bef] = dijkstra(a * K + (1 << N) - 1, M * K, g);
    double ans = inf;
    rep(cmb, 1 << N) ans = min(ans, dist[b * K + cmb]);
    return ans;
}

int main(){
    vc<double> ans;
    while (true){
        int N, M, P, a, b;cin >> N >> M >> P >> a >> b; a--; b--;
        if (N == 0) break;
        ans.push_back(solve(N, M, P, a, b));
    }
    for (auto x : ans){
        if (x == inf) cout << "Impossible" << endl;
        else cout << fixed << setprecision(16) << x << endl;
    }
}
accuracy: 1
time_ms: 80
memory_kb: 25756
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
struct SetupIO {
    SetupIO() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << fixed << setprecision(30);
    }
} setup_io;
int main(void) {
    while(1) {
        int n, m, p, a, b;
        cin >> n >> m >> p >> a >> b;
        if(n == 0) break;
        a--;
        b--;
        vector<int> t(n);
        rep(i, 0, n) {
            cin >> t[i];
        }
        vector<vector<pair<int, double>>> g(m * (1 << n));
        rep(i, 0, p) {
            int x, y, z;
            cin >> x >> y >> z;
            x--;
            y--;
            rep(mask, 0, 1 << n) {
                rep(j, 0, n) {
                    if(mask & (1 << j)) continue;
                    g[x * (1 << n) + mask].push_back({y * (1 << n) + (mask | (1 << j)), 1.0 * z / t[j]});
                    g[y * (1 << n) + mask].push_back({x * (1 << n) + (mask | (1 << j)), 1.0 * z / t[j]});
                }
            }
        }
        vector<double> d(m * (1 << n), inf);
        priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> pq;
        d[a * (1 << n)] = 0;
        pq.push({0, a * (1 << n)});
        while(!pq.empty()) {
            auto [dist, cur] = pq.top();
            pq.pop();
            if(d[cur] < dist) continue;
            for(const auto& [to, cost] : g[cur]) {
                if(d[to] > d[cur] + cost) {
                    d[to] = d[cur] + cost;
                    pq.push({d[to], to});
                }
            }
        }
        double ans = inf;
        rep(mask, 0, 1 << n) {
            ans = min(ans, d[b * (1 << n) + mask]);
        }
        if(ans == inf) {
            cout << "Impossible" << '\n';
        } else {
            cout << ans << '\n';
        }
    }
}
accuracy: 1
time_ms: 90
memory_kb: 26200
final_rank: 18

code_snippet: #include <iostream> 
#include <cmath>
#include <string.h>
#include <cstdio>
#include <algorithm>
#define LL long long
using namespace std;
const int N = 9;
double v[N], g[32][32];
double dp[1 << N][32];
int main() {
	while(true) {
		LL n, m, p, a, b; scanf("%lld%lld%lld%lld%lld", &n, &m, &p, &a, &b);
		if(n == 0 && m == 0 && p == 0 && a == 0 && b == 0) return 0;
		for (int s = 0; s < (1 << n); ++s)
			for (int i = 0; i <= m; ++i)
				dp[s][i] = 1e9;
		for (int i = 1; i <= m; ++i)
			for (int j = 1; j <= m; ++j)
				g[i][j] = 0;
		for (int i = 0; i < n; ++i) scanf("%lf", &v[i]);
		dp[0][a] = 0;
		for (int i = 1; i <= p; ++i) {
			LL x, y; double z;
			scanf("%lld%lld%lf", &x, &y, &z);
			g[x][y] = g[y][x] = z;
		}
		for (int s = 0; s < (1 << n); ++s) {
			for (int i = 1; i <= m; ++i) {
				for (int j = 1; j <= m; ++j) {
					if(g[i][j] == 0 || i == j) continue;
					for (int k = 0; k < n; ++k) {
						if((s & (1 << k)) != 0) continue;
						LL msk = s | (1 << k);
						dp[msk][j] = min(dp[msk][j], dp[s][i] + g[i][j] / v[k]);
					}
				}
			}
		}
		double ans = 1e9;
		for (int s = 0; s < (1 << n); ++s)
			ans = min(ans, dp[s][b]);
		if(ans == 1e9) printf("Impossible\n");
		else printf("%.3lf\n", ans);
	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3440
final_rank: 2

code_snippet: #include <iostream>
using namespace std;
const int MAX_N = 8;
const int MAX_M = 30;
const double INF = 10000000.0;
int d[MAX_M][MAX_M];
double dp[1 << MAX_N][MAX_M];
int T[MAX_M];
int N, M, P, A, B;
long long showBit(int num)
{
    long long res = 0LL;
    for (int i = 14; i >= 0; i--)
    {
        res = res * 10 + (num >> i & 1);
    }
    return 10000000000000000L + res;
}
void solve()
{
    fill(dp[0], dp[0] + ((1 << MAX_N) * MAX_M), INF);
    dp[(1 << N) - 1][A] = 0.0;
    for (int S = (1 << N) - 2; S >= 0; S--)
    {
        for (int v = 0; v < M; v++)
        {
            for (int u = 0; u < M; u++)
            {
                for (int k = 0; k < N; k++)
                {
                    if (!(S >> k & 1))
                    {
                        dp[S][v] = min(dp[S][v], dp[S | 1 << k][u] + (d[v][u] * 1.0) / T[k]);
                    }
                }
            }
        }
    }
}
void putAns()
{
    double ans = INF;
    for (int S = 0; S < (1 << N); S++)
    {
        ans = min(ans, dp[S][B]);
    }
    if (ans >= 1000.0)
    {
        printf("Impossible\n");
    }
    else
    {
        printf("%.3f\n", ans);
    }
}
void input()
{
    A--, B--;
    fill(d[0], d[0] + MAX_M * MAX_M, 10000000);
    for (int i = 0; i < N; i++)
    {
        scanf("%d", &T[i]);
    }
    for (int i = 0; i < M; i++)
    {
        d[i][i] = 0;
    }
    int from, to, cost;
    for (int i = 0; i < P; i++)
    {
        scanf("%d%d%d", &from, &to, &cost);
        d[--from][--to] = cost;
        d[to][from] = cost;
    }
}
int main()
{
    while (true)
    {
        scanf("%d%d%d%d%d", &N, &M, &P, &A, &B);
        if (N == 0 && M == 0 && P == 0 && A == 0 && B == 0)
        {
            break;
        }
        input();
        solve();
        putAns();
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3556
final_rank: 4