POJ2686 Traveling by Stagecoach(状压DP+SPFA)

题目大概是给一张有向图,有n张票,每张票只能使用一次,使用一张票就能用pi匹马拉着走过图上的一条边,走过去花的时间是边权/pi,问从a点走到b点的最少时间是多少。

用dp[u][S]表示当前在u点且用过的票集合是S的最少时间,丢进SPFA更新。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 using namespace std;
 5 #define INF 1e8
 6 #define MAXN 33
 7 #define MAXM 33*33
 8 struct Edge{
 9     int u,v,next;
10     double w;
11 }edge[MAXM];
12 int NE,head[MAXN];
13 void addEdge(int u,int v,double w){
14     edge[NE].u=u; edge[NE].v=v; edge[NE].w=w;
15     edge[NE].next=head[u]; head[u]=NE++;
16 }
17 struct Node{
18     int u,S;
19     Node(int _u,int _S):u(_u),S(_S){}
20 };
21 int n,m,t[8];
22 double d[31][1<<8];
23 bool vis[31][1<<8];
24 void SPFA(int vs){
25     memset(vis,0,sizeof(vis));
26     vis[vs][0]=1;
27     for(int i=1; i<=m; ++i){
28         for(int j=0; j<(1<<n); ++j) d[i][j]=INF;
29     }
30     d[vs][0]=0;
31     queue<Node> que;
32     que.push(Node(vs,0));
33     while(!que.empty()){
34         Node nd=que.front(); que.pop();
35         int u=nd.u,S=nd.S;
36         for(int i=head[u]; i!=-1; i=edge[i].next){
37             int v=edge[i].v;
38             for(int j=0; j<n; ++j){
39                 if((S>>j)&1) continue;
40                 if(d[v][S^(1<<j)]>d[u][S]+edge[i].w/t[j]){
41                     d[v][S^(1<<j)]=d[u][S]+edge[i].w/t[j];
42                     if(!vis[v][S^(1<<j)]){
43                         vis[v][S^(1<<j)]=1;
44                         que.push(Node(v,S^(1<<j)));
45                     }
46                 }
47             }
48         }
49         vis[u][S]=0;
50     }
51 }
52 int main(){
53     int p,vs,vt,a,b;
54     double c;
55     while(~scanf("%d%d%d%d%d",&n,&m,&p,&vs,&vt) && (n||m||p||vs||vt)){
56         NE=0;
57         memset(head,-1,sizeof(head));
58         for(int i=0; i<n; ++i) scanf("%d",t+i);
59         while(p--){
60             scanf("%d%d%lf",&a,&b,&c);
61             addEdge(a,b,c); addEdge(b,a,c);
62         }
63         SPFA(vs);
64         double res=INF;
65         for(int i=0; i<(1<<n); ++i){
66             res=min(res,d[vt][i]);
67         }
68         if(res==INF) puts("Impossible");
69         else printf("%f\n",res);
70     }
71     return 0;
72 } 

 

posted @ 2016-03-01 23:04  WABoss  阅读(191)  评论(0编辑  收藏  举报