POJ 2686 Traveling by Stagecoach
状压DP
dp[s][p]用了哪几张票,到哪个节点的最小费用。
注意:G++ %.3lf输出会WA,但C++能过;改成%.3f,C++,G++都能AC
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<vector> #include<map> #include<algorithm> using namespace std; const double INF = 999999999999; int n, m, p, a, b; int t[20]; struct Edge { int to; int dis; }e[1000]; int tot; vector<int>g[50]; double dp[500][50]; 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; tot = 0; for (int i = 1; i <= m; i++) g[i].clear(); for (int i = 0; i < (1 << n); i++) for (int j = 1; j <= m; j++) dp[i][j] = INF; for (int i = 0; i < n; i++) scanf("%d", &t[i]); for (int i = 1; i <= p; i++) { int u, v, c; scanf("%d%d%d", &u, &v, &c); e[++tot].to = v; e[tot].dis = c; g[u].push_back(tot); e[++tot].to = u; e[tot].dis = c; g[v].push_back(tot); } dp[0][a] = 0; for (int i = 0; i < (1 << n); i++) { for (int j = 1; j <= m; j++) { if (dp[i][j] == INF) continue; for (int k = 0; k < n; k++) { if ((i | (1 << k)) == i) continue; for (int s = 0; s < g[j].size(); s++) { dp[(i | (1 << k))][e[g[j][s]].to] = min( dp[(i | (1 << k))][e[g[j][s]].to], dp[i][j] + 1.0*e[g[j][s]].dis / (1.0*t[k])); } } } } double ans = INF; for (int i = 0; i < (1 << n); i++) ans = min(ans, dp[i][b]); if (ans == INF) printf("Impossible\n"); else printf("%.3f\n", ans); } return 0; }