[状压DP+壮压运算符理解]Traveling by Stagecoach POJ - 2686(暂未更完)

少量位运算使用理解

i 位为从右往左从0开始数
如果要设置 n 的第 i 位为1,n=(n|(1<<i);                              
如果要设置 n 的第 i 位为0,n=(n &(~(1<<i));

& 按位与
如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
l 按位或
两个相应的二进制位中只要有一个为1,该位的结果值为1
^  按位异或
若参加运算的两个二进制位值相同则为0,否则为1
~ 取反
~是一元运算符,用来对一个二进制数按位取\反,即将01,将10
<< 左移
用来将一个数的各二进制位全部左移N位,右补0
( >> 右移 
将一个数的各二进制位右移N位,移到右端 的低位被舍弃,对于无符号数,高位补0

题干

有一个人从某个城市要到另一个城市(点数<=30)
然后有n个马车票,相邻的两个城市走的话要消耗掉一个马车票。
花费的时间呢,是马车票上有个速率值,用边/速率是花的时间。
求最后这个人花费的最短时间是多少

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
#include <stack>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

const int maxn=35;
const int INF=1e9;
double dp[1<<10][maxn];
int mp[maxn][maxn];
int d[maxn];


int main(){
    int t,n,m,src,des;
    while(cin>>t>>n>>m>>src>>des&&(t+n+m+src+des)){
        memset(mp,-1,sizeof(mp));
        for(int i=0;i<t;i++) cin>>d[i];
        for(int i=1;i<=m;i++) {
            int st,ed,dis;
            cin>>st>>ed>>dis;
            if(mp[st][ed]==-1||mp[st][ed]>dis){
                mp[st][ed]=dis;
                mp[ed][st]=dis;
            } 
        }
        for(int i=0;i<(1<<9);i++){
            for(int j=0;j<maxn;j++) dp[i][j]=INF;
        }
        dp[0][src]=0;
        double ans=INF;
        for(int i=0;i<(1<<t);i++){//
            for(int u=1;u<=n;u++){
                for(int k=0;k<t;k++){
                    if(!(i&(1<<k))){//取票不冲突重复
                        for(int j=1;j<=n;j++){
                            if(mp[u][j]!=-1)dp[i|(1<<k)][j]=min(dp[i|(1<<k)][j],dp[i][u]+1.0*mp[u][j]/d[k]);
                        }
                    }
                }
            }
            ans=min(ans,dp[i][des]);
        }
        if(ans==INF) cout<<"Impossible\n";
        else printf("%.3f\n",ans);//poj %lf wa飞。。。 看discuss 才知道poj坑人。。
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40831340/article/details/81502522
今日推荐