poj 2686 Traveling by Stagecoach(状压dp)

题目链接

题意:有n张车票,m座城市,p条路,求从a到b的最小时间,无法到达则输出“Impossible”;

每张车票的时间是城市间的距离处以马匹数量;

用状态压缩dp;

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;

const int INF=0x3f3f3f3f;
const int maxn = 35;
int t[maxn];//每张车票对应的马的匹数
double dp[1<<17][maxn];
//dp[s][v] s是已经用过的车票集合,v是要到的城市,dp[s][v]是当前集合到v的最小时间
int dis[maxn][maxn];//距离,没有边是-1

int main()
{
    int n,m,p,a,b;
    while(cin>>n>>m>>p>>a>>b && n+m+p+a+b){
        for(int i = 0;i < n;i++) cin>>t[i];
        memset(dis,-1,sizeof(dis));
        for(int i = 0;i < p;i++){
            int x,y,z;
            cin>>x>>y>>z;
            dis[x][y]=dis[y][x]=z;
        }
        for(int i = 0;i < (1<<9);i++)
            fill(dp[i],dp[i]+maxn,INF);//给double型的dp赋值
        /*for(int i = 0;i < (1<<9);i++)
            for(int j = 0;j < maxn;j++)
                dp[i][j] = INF;*/
        dp[0][a] = 0;
        double ans = INF;
		int i,j,u,v;
        for(i = 0;i < (1<<n);i++){
            for(u = 1;u <= m;u++){
                for(v = 0;v < n;v++)
                    if(!(i&(1<<v)))
                        for(j = 1;j <= m;j++)
                            if(dis[u][j]!=-1)//有边
                                dp[i|(1<<v)][j] = min(dp[i|(1<<v)][j],dp[i][u]+1.0*dis[u][j]/t[v]);
			}
				ans = min(ans,dp[i][b]);
        }
        if(ans == INF) cout<<"Impossible"<<endl;
        else printf("%.3f\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42754600/article/details/81663815
今日推荐