题目链接:http://poj.org/problem?id=2686
思路:典型的状压dp题,dp[s][v]表示到达剩下的车票集合为S并且现在在城市v的状态所需要的最小的花费。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define inf 1<<30 int n,m,p,a,b;
int t[];
int map[][];
double dp[<<][];//到达剩下的车票集合为S,并且现在在城市v的状态所需要的最小的花费 int main()
{
int u,v,w;
while(~scanf("%d%d%d%d%d",&n,&m,&p,&a,&b)){
if(n==&&m==&&p==&&a==&&b==)break;
for(int i=;i<m;i++)
for(int j=;j<m;j++)
map[i][j]=(i==j)?:inf;
for(int i=;i<n;i++)scanf("%d",&t[i]);
while(p--){
scanf("%d%d%d",&u,&v,&w);
map[u-][v-]=w;
map[v-][u-]=w;
}
for(int state=;state<(<<n);state++){
fill(dp[state],dp[state]+m,inf);
}
dp[(<<n)-][a-]=;
double ans=inf;
for(int state=(<<n)-;state>=;state--){
ans=min(ans,dp[state][b-]);
for(int u=;u<m;u++){
for(int i=;i<n;i++){
if((state>>i)&){
for(int v=;v<m;v++){
if(map[u][v]<inf&&dp[state][u]<inf){
dp[state&~(<<i)][v]=min(dp[state&~(<<i)][v],dp[state][u]+(double)map[u][v]/t[i]);
}
}
}
}
}
}
if(ans==inf){
puts("Impossible");
}else
printf("%.3f\n",ans);
}
return ;
}