• [题解]UVA10801 Lift Hopping


    链接:http://vjudge.net/problem/viewProblem.action?id=22172

    描述:有n部电梯,每部电梯都有不能停下的楼层,要求搭乘电梯从第0层到第k层。

    思路:单源点最短路

            建图:将每层楼拆成n个点,用边权解决换乘等待的时间。将每部电梯能到达的楼层顺次连接,边权是该电梯经过所需时间。最后建立一个超级源点S,连接每部电梯的第0层的节点,边权为0,方便统计答案。

    下面是我的实现,Dijkstra版本:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <queue>
      5 using namespace std;
      6 #define MaxN 520
      7 #define MaxM 3020
      8 #define Max_n 8
      9 #define S 500
     10 #define INF 100000
     11 struct node
     12 {
     13     int v,dist;
     14     node *next;
     15 };
     16 node Edge[MaxM];
     17 node *cnt=&Edge[0];
     18 node *adj[MaxN];
     19 int dist[MaxN];
     20 int T[Max_n];
     21 int n,K,Ans;
     22 bool For_Build[MaxN];
     23 inline void Clean()
     24 {
     25     memset(Edge,0,sizeof(Edge));
     26     cnt=&Edge[0];
     27     memset(adj,0,sizeof(adj));
     28 }
     29 inline void Addedge(int u,int v,int w)
     30 {
     31     node *p=++cnt;
     32     p->v=v;
     33     p->dist=w;
     34     p->next=adj[u];
     35     adj[u]=p;
     36 
     37     p=++cnt;
     38     p->v=u;
     39     p->dist=w;
     40     p->next=adj[v];
     41     adj[v]=p;
     42 }
     43 inline void Read_Build()
     44 {
     45     int i,j,Num,f1,f2;
     46     for(i=1;i<=n;i++)
     47         scanf("%d",&T[i]);
     48     for(i=1;i<=n;i++)
     49     {
     50         Num=100*(i-1);
     51         Addedge(S,Num,0);
     52         f1=-1;
     53         do
     54         {
     55             scanf("%d",&f2);For_Build[Num+f2]=true;
     56             if(f1!=-1)
     57                 Addedge(Num+f1,Num+f2,(f2-f1)*T[i]);
     58             f1=f2;
     59             for(j=1;j<i;j++)
     60                 if(For_Build[100*(j-1)+f2])
     61                     Addedge(100*(j-1)+f2,Num+f2,60);
     62         }while(getchar()!='
    ');
     63     }
     64 }
     65 struct cmp
     66 {
     67     bool operator()(node a,node b)
     68     {
     69         return a.dist>b.dist;
     70     }
     71 };
     72 priority_queue <node, vector<node>, cmp> q;
     73 void Dijkstra(int s)
     74 {
     75     node c,d;
     76     node *p;
     77     int i,j,k;
     78     memset(dist,0x3f,sizeof(dist));
     79     dist[s]=0;
     80     c.v=s;c.dist=0;
     81     q.push(c);
     82     while(!q.empty())
     83     {
     84         d=q.top();q.pop();
     85         j=d.v;
     86         for(p=adj[j];p!=NULL;p=p->next)
     87         {
     88             k=p->v;
     89             if(dist[k]>dist[j]+p->dist)
     90             {
     91                 dist[k]=dist[j]+p->dist;
     92                 d.v=k;d.dist=dist[k];
     93                 q.push(d);
     94             }
     95         }
     96     }
     97 }
     98 inline void Print()
     99 {
    100     int i;
    101     for(i=1;i<=n;i++)
    102         Ans=min(Ans,dist[100*(i-1)+K]);
    103     if(Ans==INF)
    104         printf("IMPOSSIBLE
    ");
    105     else
    106         printf("%d
    ",Ans);
    107 }
    108 int main()
    109 {
    110     while(scanf("%d%d",&n,&K)!=EOF)
    111     {
    112         Clean();
    113         Read_Build();
    114         Dijkstra(S);
    115         Ans=INF;
    116         Print();
    117     }
    118     return 0;
    119 }
    View Code

     我是用拆点的方法解决换乘等待的时间问题的,在网上看到另一种处理方式感觉很科学。本以为我的会很慢,实践证明还是算比较快的了,也可能是数据不强。

    然后我再试了试spfa,稍微慢一点:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <queue>
      5 using namespace std;
      6 #define MaxN 520
      7 #define MaxM 3020
      8 #define Max_n 8
      9 #define S 500
     10 #define INF 100000
     11 struct node
     12 {
     13     int v,dist;
     14     node *next;
     15 };
     16 node Edge[MaxM];
     17 node *cnt=&Edge[0];
     18 node *adj[MaxN];
     19 int dist[MaxN];
     20 int T[Max_n];
     21 int n,K,Ans;
     22 bool For_Build[MaxN],vis[MaxN];
     23 inline void Clean()
     24 {
     25     memset(Edge,0,sizeof(Edge));
     26     cnt=&Edge[0];
     27     memset(adj,0,sizeof(adj));
     28 }
     29 inline void Addedge(int u,int v,int w)
     30 {
     31     node *p=++cnt;
     32     p->v=v;
     33     p->dist=w;
     34     p->next=adj[u];
     35     adj[u]=p;
     36 
     37     p=++cnt;
     38     p->v=u;
     39     p->dist=w;
     40     p->next=adj[v];
     41     adj[v]=p;
     42 }
     43 inline void Read_Build()
     44 {
     45     int i,j,Num,f1,f2;
     46     for(i=1;i<=n;i++)
     47         scanf("%d",&T[i]);
     48     for(i=1;i<=n;i++)
     49     {
     50         Num=100*(i-1);
     51         Addedge(S,Num,0);
     52         f1=-1;
     53         do
     54         {
     55             scanf("%d",&f2);For_Build[Num+f2]=true;
     56             if(f1!=-1)
     57                 Addedge(Num+f1,Num+f2,(f2-f1)*T[i]);
     58             f1=f2;
     59             for(j=1;j<i;j++)
     60                 if(For_Build[100*(j-1)+f2])
     61                     Addedge(100*(j-1)+f2,Num+f2,60);
     62         }while(getchar()!='
    ');
     63     }
     64 }
     65 queue<int>q;
     66 void Spfa(int s)
     67 {
     68     int j,k;
     69     memset(dist,0x3f,sizeof(dist));
     70     dist[s]=0;
     71     q.push(s);
     72     vis[s]=true;
     73     while(!q.empty())
     74     {
     75         j=q.front();
     76         q.pop();
     77         vis[j]=false;
     78         for(node *p=adj[j];p!=NULL;p=p->next)
     79         {
     80             k=p->v;
     81             if(dist[k]>dist[j]+p->dist)
     82             {
     83                 dist[k]=dist[j]+p->dist;
     84                 if(!vis[k])
     85                 {
     86                     q.push(k);
     87                     vis[k]=true;
     88                 }
     89             }
     90         }
     91     }
     92 }
     93 inline void Print()
     94 {
     95     int i;
     96     for(i=1;i<=n;i++)
     97         Ans=min(Ans,dist[100*(i-1)+K]);
     98     if(Ans==INF)
     99         printf("IMPOSSIBLE
    ");
    100     else
    101         printf("%d
    ",Ans);
    102 }
    103 int main()
    104 {
    105     while(scanf("%d%d",&n,&K)!=EOF)
    106     {
    107         Clean();
    108         Read_Build();
    109         Spfa(S);
    110         Ans=INF;
    111         Print();
    112     }
    113     return 0;
    114 }
    View Code

  • 相关阅读:
    Shell中判断语句if中-z至-d的意思
    每日英语-20171129
    THINK PHP 学习笔记20171115
    每日英语-20171115
    git bash安装和基本设置
    Centos6.8搭建Git服务(git版本可选)
    一键安装lamp环境出现的问题
    用PHP实现反向代理服务器
    动词的过去式、过去分词、现在分词
    树莓派 中文
  • 原文地址:https://www.cnblogs.com/CQBZOIer-zyy/p/3824872.html
Copyright © 2020-2023  润新知