POJ 2686 Traveling by Stagecoach

传送门:http://poj.org/problem?id=2686

题意:

  一张图有m(m<=100)个点,一个人想从a点乘马车走到b点,他有n(n<=8)张车票,每张车票有一个val为这张车票可以使用的马的数量,马车每到一个地方就要换乘一次,每次换乘会消耗一张车票,消耗当前这条路长度除以车票的val。求走到b点的最短时间。

题解:

  看到题目很容易想到这是一道TSP,但是不同于一般TSP,这道题的点数有点大,于是我们不能通过直接表示走过哪些点求解。

  这个题还有个关键元素那就是票,票的数量小于等于8,所以我们考虑通过票的使用来进行状态转移。

  dp[i][j]表示票的使用为i的状态下最后走到j所需的最小时间。

 1 #include <iostream>
 2 #include <vector>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cstdio>
 6 using namespace std;
 7 const int INF=0x3f3f3f3f;
 8 typedef long long ll;
 9 int n,m,p,a,b,u,v,w,mx,tck[200];
10 double dp[600][105],ans;
11 struct node {
12     int x,y;
13     node(){}
14     node(int c, int d) {x=c;y=d;}
15 };
16 vector<node> g[102];
17 void init() {
18     ans=INF; mx=1<<n;
19     for(int i=0;i<102;++i) g[i].clear();
20     for(int i=0;i<mx;++i) fill(dp[i],dp[i]+m+1,INF);
21     dp[0][a]=0;
22 }
23 
24 int main() {
25     //freopen("in.txt", "r", stdin);
26     while(~scanf("%d%d%d%d%d",&n,&m,&p,&a,&b)) {
27         if(!(n|m|p|a|b)) break;
28         init();
29         for(int i=1;i<=n;++i) scanf("%d",&tck[i]);
30         for(int i=1;i<=p;++i) {
31             scanf("%d%d%d",&u,&v,&w);
32             g[v].push_back(node(u,w)); g[u].push_back(node(v,w));
33         }
34         for(int i=0;i<mx;++i) for(int j=1;j<=m;++j) if(dp[i][j]<1e7){
35             for(int pos=0;pos<g[j].size();++pos)for(int k=1;k<=n;++k)if(~i&(1<<k-1)){
36                 node x=g[j][pos];u=i|(1<<k-1);
37                 dp[u][x.x]=min(dp[u][x.x],dp[i][j]+1.0*x.y/tck[k]);
38                 if(x.x==b) ans=min(ans,dp[u][x.x]);
39             }
40         }
41         if(ans>1e7) printf("Impossible\n");
42         else printf("%.5f\n",ans);
43     }
44     return 0;
45 }
View Code

 

posted on 2017-08-18 10:54  仰望咸鱼Orzzzz  阅读(166)  评论(0编辑  收藏  举报

导航