题意:有n张车票,m座城市,p条路,求从a到b的最小时间,无法到达则输出“Impossible”;
每张车票的时间是城市间的距离处以马匹数量;
用状态压缩dp;
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn = 35;
int t[maxn];//每张车票对应的马的匹数
double dp[1<<17][maxn];
//dp[s][v] s是已经用过的车票集合,v是要到的城市,dp[s][v]是当前集合到v的最小时间
int dis[maxn][maxn];//距离,没有边是-1
int main()
{
int n,m,p,a,b;
while(cin>>n>>m>>p>>a>>b && n+m+p+a+b){
for(int i = 0;i < n;i++) cin>>t[i];
memset(dis,-1,sizeof(dis));
for(int i = 0;i < p;i++){
int x,y,z;
cin>>x>>y>>z;
dis[x][y]=dis[y][x]=z;
}
for(int i = 0;i < (1<<9);i++)
fill(dp[i],dp[i]+maxn,INF);//给double型的dp赋值
/*for(int i = 0;i < (1<<9);i++)
for(int j = 0;j < maxn;j++)
dp[i][j] = INF;*/
dp[0][a] = 0;
double ans = INF;
int i,j,u,v;
for(i = 0;i < (1<<n);i++){
for(u = 1;u <= m;u++){
for(v = 0;v < n;v++)
if(!(i&(1<<v)))
for(j = 1;j <= m;j++)
if(dis[u][j]!=-1)//有边
dp[i|(1<<v)][j] = min(dp[i|(1<<v)][j],dp[i][u]+1.0*dis[u][j]/t[v]);
}
ans = min(ans,dp[i][b]);
}
if(ans == INF) cout<<"Impossible"<<endl;
else printf("%.3f\n",ans);
}
return 0;
}