• 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
    ",res);
    70     }
    71     return 0;
    72 } 
  • 相关阅读:
    QuickContactBadge
    第一周——15选1
    UVA 10036 Divisibility
    POJ 3984 迷宫问题
    POJ 3258 River Hopscotch
    CodeForces 230A Dragons
    HDU 4450 Draw Something
    POJ 2485(PRIME算法)
    HDU 1213
    CodeForces 16E
  • 原文地址:https://www.cnblogs.com/WABoss/p/5233253.html
Copyright © 2020-2023  润新知