Description
Input
Output
Sample Input
3 4 3 1 4 3 1 2 1 2 10 2 3 30 3 4 20 2 4 4 2 1 3 1 2 3 3 1 3 3 4 1 2 4 2 5 2 4 3 4 1 5 5 1 2 10 2 3 10 3 4 10 1 2 0 1 2 1 8 5 10 1 5 2 7 1 8 4 5 6 3 1 2 5 2 3 4 3 4 7 4 5 3 1 3 25 2 4 23 3 5 22 1 4 45 2 5 51 1 5 99 0 0 0 0 0
Sample Output
30.000 3.667 Impossible Impossible 2.856
Hint
30.0 3.66667 Impossible Impossible 2.85595
题意:m个城市,p条路,告诉你每条路长度,给你n张车票,每张车票都有一个车速。一条路必须要用掉一张车票,时间为距离/车速。求从a到b所需的最短时间。
题解:状态压缩dp,dp[s][v]表示还剩的车票集合为s,在v城市时最短时间,那么
dp[s][v] = min{ dp[s-{i}][u] + d(v, u) }
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <map>
#include <vector>
#include <list>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <limits>
#include <new>
#include <utility>
#include <iterator>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <ctime>
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 10;
const int maxm = 35;
double dp[(1<<maxn)-1][maxm];
int d[maxm][maxm];
int t[maxn];
int vis[maxm];
int n, m, p, a, b;
double rec(int s, int v)
{
    vis[v] = 1;
    if (dp[s][v] >= 0)
        return dp[s][v];
    if (v == b)
        return dp[s][v] = 0;
    double res = INF;
    for (int u = 0; u < m; ++u)
        for (int i = 0; i < n; ++i)
            if (u != v && !vis[u] && (1<<i)&s && d[u][v] < INF)
            {
                vis[u] = 1;
                res = min(res, rec((1<<i)^s, u)+d[v][u]*1.0/t[i]);
                vis[u] = 0;
            }
    return dp[s][v] = res;
}
int main()
{
    while (cin >> n >> m >> p >> a >> b && (n || m || p || a || b))
    {
        a--;
        b--;
        for (int i = 0; i < n; ++i)
            scanf("%d", &t[i]);
        fill(d[0], d[m], INF);
        fill(vis, vis+m, 0);
        fill(dp[0], dp[1<<n], -1);
        while (p--)
        {
            int x, y, dis;
            scanf("%d%d%d", &x, &y, &dis);
            d[x-1][y-1] = d[y-1][x-1] = dis;
        }
        double ans = rec((1<<n)-1, a);
        if (fabs(ans-INF) < 1e-8)
            printf("Impossible\n");
        else
            printf("%.3f\n", ans);
    }
    return 0;
}
版权声明:本文为博主原创文章,转载请注明出处。
poj2686(Traveling by Stagecoach)状态压缩dp
原文地址:http://blog.csdn.net/god_weiyang/article/details/47782345