Traveling by Stagecoach 状态压缩裸题

本文介绍了一种使用动态规划解决舞台剧旅行问题的方法。通过枚举所有可能的状态,计算从起点到各个城市的最短路径。适用于需要规划路径并考虑不同票种约束条件的旅行场景。

                              Traveling by Stagecoach

 

 

dp[s][v]  从源点到达  v,状态为s,v的最小值。  for循环枚举就行了。

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <string>
 7 #include <vector>
 8 #include <set>
 9 #include <map>
10 #include <stack>
11 #include <queue>
12 #include <sstream>
13 #include <iomanip>
14 using namespace std;
15 typedef long long LL;
16 const double INF=0x4fffffff;
17 const double EXP=1e-5;
18 const int MS=10;
19 const int SIZE=31;
20 
21 double dp[1<<MS][SIZE];
22 
23 int edges[SIZE][SIZE];
24 int cnt[MS];
25 
26 int start,final,tickets,citys,edge;
27 
28 void solve()
29 {
30       for(int i=0;i<(1<<tickets);i++)
31             fill(dp[i],dp[i]+SIZE,INF);
32       dp[(1<<tickets)-1][start-1]=0;
33       double res=INF;
34       for(int i=(1<<tickets)-1;i>=0;i--)
35       {
36             res=min(res,dp[i][final-1]);
37             for(int u=0;u<citys;u++)
38             {
39                   for(int j=0;j<tickets;j++)
40                   {
41                         if((i>>j)&1)
42                         {
43                               for(int v=0;v<citys;v++)
44                                     if(edges[u][v]>=0)
45                                     dp[i-(1<<j)][v]=min(dp[i-(1<<j)][v],dp[i][u]+double(edges[u][v])/cnt[j]);
46                         }
47                   }
48             }
49       }
50       if(res+EXP>=INF)
51             printf("Impossible\n");
52       else
53             printf("%.3lf\n",res);
54 }
55 
56 int main()
57 {
58       while(scanf("%d%d%d%d%d",&tickets,&citys,&edge,&start,&final)==5&&tickets)
59       {
60 
61             for(int i=0;i<tickets;i++)
62             {
63                   scanf("%d",&cnt[i]);
64             }
65             memset(edges,-1,sizeof(edges));
66             for(int i=0;i<edge;i++)
67             {
68                   int x,y,z;
69                   scanf("%d%d%d",&x,&y,&z);
70                   edges[x-1][y-1]=edges[y-1][x-1]=z;
71             }
72             solve();
73       }
74       return 0;
75 }

 

转载于:https://www.cnblogs.com/767355675hutaishi/p/4394022.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值