题目链接:http://poj.org/problem?id=2686
题意:有m个城市互相连接,每一条道路有一个距离。现在有n张车票,每张车票上都记有马的匹数且只能用一次,从一个城市移动到另一个城市所需的时间等于城市之间道路的长度除以马的数量的结果,求从城市a到城市b的最短时间。
思路:状态压缩DP,因为车票只能用一次,所以我们记录车票使用情况的状态,以及当前所在的城市编号进行dp。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <utility>
using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;i++)
#define Rrep(i,j,k) for (int i=j;i>=k;i--)
#define Clean(x,y) memset(x,y,sizeof(x))
#define LL long long
#define ULL unsigned long long
#define inf 111111111
#define mod %100000007
int n,m,p,st,ed;
double dp[1<<8][31];
int dis[31][31];
int x[10];
int main()
{
while( scanf("%d%d%d%d%d",&n,&m,&p,&st,&ed) == 5 )
{
if ( n + m + p + st + ed == 0 ) break;
Clean(dis,-1);
int uplim = 1<<n;
rep(i,1,n) scanf("%d",x+i);
rep(i,1,p)
{
int tx,ty,tz;
scanf("%d%d%d",&tx,&ty,&tz);
dis[tx][ty] = tz;
dis[ty][tx] = tz;
}
double ans = inf;
rep(i,0,uplim-1) fill(dp[i],dp[i]+m+1,inf);
dp[0][st] = 0;
rep(s,1,uplim-1)
{
rep(v,1,m)
rep(i,1,n)
if ( s & 1<<(i-1) )
{
rep(j,1,m)
if ( dis[v][j] > 0 ) dp[s][v] = min( dp[s][v] , dp[s & ~( 1<<(i-1) )][j] + double(dis[v][j])/x[i] );
}
ans = min( ans , dp[s][ed] );
}
if ( ans == inf ) puts("Impossible");
else printf("%0.3f\n",ans);
}
return 0;
}