[题解]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()!='\n');
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\n");
105 else
106 printf("%d\n",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 }
我是用拆点的方法解决换乘等待的时间问题的,在网上看到另一种处理方式感觉很科学。本以为我的会很慢,实践证明还是算比较快的了,也可能是数据不强。

然后我再试了试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()!='\n');
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\n");
100 else
101 printf("%d\n",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 }

[题解]UVA10801 Lift Hopping的更多相关文章
- UVA-10801 Lift Hopping (最短路)
题目大意及分析:一道简单的最短路...好几天没写程序了,憋得难受!!! 代码如下: # include<iostream> # include<cstdio> # includ ...
- uva 10801 - Lift Hopping(最短路Dijkstra)
/* 题目大意: 就是一幢大厦中有0-99的楼层, 然后有1-5个电梯!每个电梯有一定的上升或下降速度和楼层的停止的位置! 问从第0层楼到第k层最少经过多长时间到达! 思路:明显的Dijkstra , ...
- UVA 10801 Lift Hopping 电梯换乘(最短路,变形)
题意: 有n<6部电梯,给出每部电梯可以停的一些特定的楼层,要求从0层到达第k层出来,每次换乘需要60秒,每部电梯经过每层所耗时不同,具体按 层数*电梯速度 来算.问经过多少秒到达k层(k可以为 ...
- UVa 10801 Lift Hopping【floyd 】
题意:给出n个电梯,每个电梯的运行时间,每个电梯只能在相应的楼层停靠,而且没有楼梯,再给出想去的楼层,问从0层能否到达想去的楼层,求到达的最短时间 建图还是没有建出来--- 因为n<100,可以 ...
- UVa 10801 - Lift Hopping(dijkstra最短路)
根据题意,以每一层楼为顶点,每个电梯可以到达的两层楼之间的秒数为每一条边的权值,以此构建一个无向图.然后利用dijkstra求出最短的时间,注意每次换乘电梯需要等待60s(因为同一个电梯上的楼层是相互 ...
- UVa 10801 Lift Hopping / floyd
乘电梯 求到目标层的最短时间 有n个电梯 换一个电梯乘需要额外60秒 所以建图时每个电梯自己能到的层数先把时间算好 这是不需要60秒的 然后做floyd时 如果松弛 肯定是要换电梯 所以要加60秒 # ...
- UVA 10801 Lift Hopping
算是一道需要动脑筋的最短路问题了,关键在于建图部分,对于n个电梯中每一个都要经过cnt个楼层,a[0],a[1],a[2],a[3],a[4],......a[cnt-1],那么对于任意两个楼层a[j ...
- UVA 10801 Lift Hopping 最短路
2种方式直接代码就可以了.注意首次不需要60S的转换 #include <map> #include <set> #include <list> #include ...
- UVa 10801 Lift Hopping (Dijkstra)
题意:有一栋100层的大楼(标号为0~99),里面有n个电梯(不超过5个),以及要到达的层数(aid),然后是每个电梯走一层所需的时间, 再n行就是对应每个电梯可以到达的层数,数量不定.然后每装换一次 ...
随机推荐
- 网络编程-HTTP cookie
目录 1.cookie的起源 2.cookie是什么? 3.创建cookie 3.1.响应首部 Set-Cookie 3.2.请求首部 Cookie 3.3.Document.cookie 4.HTT ...
- Book of the Dead 死者之书Demo工程回顾与学习
1.前言 一转眼离Book of the Dead Environment Demo开放下载已过去多年,当时因为技术力有限,以及对HDRP理解尚浅, 所以这篇文章一直搁浅到了现在.如今工作重心已转向U ...
- 【记录一个问题】android opencl c++: 使用event.SetCallBack()方法后,在回调函数中要再使用event.wait()才能得到profile信息
如题:希望执行完成后得到各个阶段的执行时间,但是通过回调发现start, end, submit, queued等时间都是0 因此要在回调函数中再使用一次event.wait(),然后才能获得prof ...
- centos下python2升级为python3
1.下载 下载地址 https://www.python.org/downloads/release/python-353/ 选择"Gzipped source tarball"这 ...
- (2)puppet单机测试命令apply
单机测试apply命令: 以独立的方式,将清单中的配置应用于本机,也就是说,根据配置清单配置当前服务器. 1.apply这个子命令有很多选项,而我们常用的有debug.verbose.noop等,de ...
- VUE3 之 多个 v-model 绑定及 v-model 修饰符的使用 - 这个系列的教程通俗易懂,适合新手
1. 概述 洛克定律告诉我们: 当我们的目标很远大,远到我们都看不到终点时,放弃几率就会很大,就像跑马拉松比赛,由于时间长.距离长,很多选手都会选择在中途放弃. 其实有个好办法,就是拆分,把大目标拆分 ...
- NGINX的动静分离;什么是负载均衡
目录 一:动静分离 二:负载均衡 一:动静分离 动静分离是指在 web 服务器架构中,将静态页面与动态页面或者静态内容接口和动态内容接口分开不同系统访问的架构设计方法,进而提示整个服务的访问性和可维护 ...
- TF-IDF计算相似度为什么要对稀疏向量建立索引?
TF-IDF的向量表示的稀疏问题 之前在看tf-idf代码时候思考了一个问题,不知道对于初学的大部分同学有没有这样一个疑惑,用tf-idf值构成的向量,维度可能跟词表的大小有关,那么对于一句话来说,这 ...
- 人口信息普查系统-JavaWeb-一
建民说要期中考试了,我赶紧翻阅了去年的考试题目,去年的试题是要求做一个人口普查系统.我就试着做了一下,今天主要和大家分享题目要求. 其中考试确实有些难度,用到了许多没有接触过的知识,比如JavaScr ...
- FreeSWITCH 对接RTSP和RTMP视频
在某些场景需要把摄像头或者其它推流视频加入FreeSWITCH.因此可以采用如下方式处理: 安装mod_vlc 然后在配置文件中加入 < action applicaiton="pla ...