POJ 2686(状压DP

题目:

大意是有一个人从某个城市要到另一个城市(点数<=30)

然后有n个马车票,相邻的两个城市走的话要消耗掉一个马车票。

花费的时间呢,是马车票上有个速率值,用边/速率就是花的时间。

问最后这个人花费的最短时间是多少

第一次做状压感觉那一长串for显示了这是个多么暴力的算法呢。。。1A了倒是挺顺的

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<utility>
#include<vector>
#include<cstring>
#include<cmath>
#define INF 0x3fffffff
#define pb push_back
#define pn(x) cerr<<x<<endl

using namespace std;
typedef long long ll;
const int maxv=100005;

int n,m,p,a,b;
int t[10];
int G[35][35];
double dp[35][1<<9];////记录顶点和用掉的票的集合
int main(){
////freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    while(cin>>n>>m>>p>>a>>b){
        memset(G,0,sizeof G);
        if(!(n||m||p||a||b)) break;
        for(int i=0;i<n;i++) cin>>t[i];
        for(int i=0;i<p;i++){
            int v1,v2,w;
            scanf("%d%d%d",&v1,&v2,&w);
            G[v1][v2]=G[v2][v1]=w;
        }
        for(int i=0;i<35;i++) 
            for(int j=0;j<1<<9;j++) dp[i][j]=1e10;
        dp[a][0]=0;
        for(int used=0;used<1<<n;used++)
            for(int i=1;i<=m;i++)
                for(int j=0;j<n;j++)
                    if(used&1<<j)
                        for(int k=1;k<=m;k++)
                            if(G[i][k])
                                dp[k][used]=min(dp[k][used],dp[i][used&~(1<<j)]+G[i][k]/(double)t[j]);
        double ans=1e11;
        for(int i=0;i<1<<n;i++) ans=min(ans,dp[b][i]);
        if(ans>1e9) cout<<"Impossible"<<endl;
        else cout<<ans<<endl;
    }
    return 0;
}

 

posted @ 2015-05-08 20:33  PlusSeven  阅读(135)  评论(0编辑  收藏  举报