题目链接
解析
状态:现在在城市u,此时还剩下的车票集合为S
dp[S][u]
就是这个状态。
从这个状态出发,使用一张车票
i
在
代码
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const double inf = 0x3f3f3f3f;
const int maxn = 10;
const int maxm = 50;
int t[maxn];
int d[maxm][maxm];
double dp[1<<maxn][maxm];
int n, m, p, a, b;
//dp[S][u] 表示当前车票的集合S在u城市的最小花费。
void solve() {
for (int i=0; i<(1<<n); i++)
fill(dp[i], dp[i]+m, inf);
dp[(1<<n)-1][a-1] = 0;
double res = inf;
for (int S=(1<<n)-1; S>=0; S--) { //枚举集合所有的元素
res = min(res, dp[S][b-1]); //当前集合中到终点的最小花费
for (int u=0; u<m; u++) { //当前在u城市
for (int i=0; i<n; i++) { //在u城市用i车票
if (S>>i & 1) {
for (int v=0; v<m; v++) {//用i车票u到v城市的花费
if(d[u][v] >= 0)
dp[S & ~(1<<i)][v] = min(dp[S & ~(1<<i)][v]
, dp[S][u]+d[u][v]*1.0/(1.0*t[i])); //用了i车票取最小花费
}
}
}
}
}
if (res == inf)
puts("Impossible");
else
printf("%.3f\n", res);
}
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;
for (int i=0; i<n; i++)
scanf("%d", &t[i]);
memset(d, -1, sizeof(d));
for (int i=0; i<p; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
d[u-1][v-1] = w;
d[v-1][u-1] = w;
}
solve();
}
return 0;
}