您的位置:首页 > 其它

POJ 2686 Traveling by Stagecoach(状压DP)

2015-08-06 19:03 316 查看
思路:

设dp[S][v] := 到达剩下的车票集合为S, 并且现在在城市v的状态所需要的最小花费

从这个状态出发,使用一张车票i∈S便可以移动到一个相邻的顶点u,费用加上d[v][u] / t[i];

使用过车票i之后的S变为 S & ~( 1<<i )



故dp[S & ~ (1<<i)][u] = min(dp[S & ~(1<<i)][u] , dp[S][v] + d[v][u] / t[i])

限制:

1<= n <= 8

2 <= m <= 30

1 <= a, b <= m(a != b)

1 <= t <= 10

1 <= d <= 100

/***********************************************
 * Author: fisty
 * Created Time: 2015-08-05 20:29:02
 * File Name   : poj2686.cpp
 *********************************************** */
#include <iostream>
#include <cstring>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <algorithm>
using namespace std;
#define Debug(x) cout << #x << " " << x <<endl
#define Memset(x, a) memset(x, a, sizeof(x))
const int INF = 0x3f3f3f3f;
typedef long long LL;
typedef pair<int, int> P;
#define FOR(i, a, b) for(int i = a;i < b; i++)
#define lson l, m, k<<1
#define rson m+1, r, k<<1|1
#define MAX_N 9
#define MAX_M 31
int n, m, p, a, b;
int t[MAX_N];
int d[MAX_M][MAX_M];
double dp[1<<MAX_N][MAX_M];   
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 ans = INF;
    for(int s = (1<<n)-1; s >= 0; s--){
        ans = min(dp[s][b-1], ans);
        for(int v = 0;v < m; v++){
            for(int i = 0;i < n; i++){
                if((1<<i)&s){
                    for(int u = 0;u < m; u++){
                        if(d[v][u] >= 0){
                            dp[s & ~(1<<i)][u] = min(dp[s & ~(1<<i)][u], dp[s][v] + ((double)d[v][u] / t[i]));
                        }
                    }
                }
            }
        }
    }
    if(ans == INF){
        printf("Impossible\n");
    }else{
        printf("%.3f\n", ans);
    }
}
int main() {
    //freopen("in.cpp", "r", stdin);
    //cin.tie(0);
    //ios::sync_with_stdio(false);
    while(~scanf("%d%d%d%d%d", &n, &m, &p, &a, &b)){
        if(!n && !m && !p && !a && !b) break;
        Memset(d, -1); 
        Memset(t, 0);
        for(int i = 0;i < n; i++){
            scanf("%d", &t[i]);
        }
        for(int i = 0;i < p; i++){
            int u, v, cost;
            scanf("%d%d%d", &u, &v, &cost);
            d[u-1][v-1] = cost;
            d[v-1][u-1] = cost;
        }
        solve();
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: