链接: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的更多相关文章

  1. UVA-10801 Lift Hopping (最短路)

    题目大意及分析:一道简单的最短路...好几天没写程序了,憋得难受!!! 代码如下: # include<iostream> # include<cstdio> # includ ...

  2. uva 10801 - Lift Hopping(最短路Dijkstra)

    /* 题目大意: 就是一幢大厦中有0-99的楼层, 然后有1-5个电梯!每个电梯有一定的上升或下降速度和楼层的停止的位置! 问从第0层楼到第k层最少经过多长时间到达! 思路:明显的Dijkstra , ...

  3. UVA 10801 Lift Hopping 电梯换乘(最短路,变形)

    题意: 有n<6部电梯,给出每部电梯可以停的一些特定的楼层,要求从0层到达第k层出来,每次换乘需要60秒,每部电梯经过每层所耗时不同,具体按 层数*电梯速度 来算.问经过多少秒到达k层(k可以为 ...

  4. UVa 10801 Lift Hopping【floyd 】

    题意:给出n个电梯,每个电梯的运行时间,每个电梯只能在相应的楼层停靠,而且没有楼梯,再给出想去的楼层,问从0层能否到达想去的楼层,求到达的最短时间 建图还是没有建出来--- 因为n<100,可以 ...

  5. UVa 10801 - Lift Hopping(dijkstra最短路)

    根据题意,以每一层楼为顶点,每个电梯可以到达的两层楼之间的秒数为每一条边的权值,以此构建一个无向图.然后利用dijkstra求出最短的时间,注意每次换乘电梯需要等待60s(因为同一个电梯上的楼层是相互 ...

  6. UVa 10801 Lift Hopping / floyd

    乘电梯 求到目标层的最短时间 有n个电梯 换一个电梯乘需要额外60秒 所以建图时每个电梯自己能到的层数先把时间算好 这是不需要60秒的 然后做floyd时 如果松弛 肯定是要换电梯 所以要加60秒 # ...

  7. UVA 10801 Lift Hopping

    算是一道需要动脑筋的最短路问题了,关键在于建图部分,对于n个电梯中每一个都要经过cnt个楼层,a[0],a[1],a[2],a[3],a[4],......a[cnt-1],那么对于任意两个楼层a[j ...

  8. UVA 10801 Lift Hopping 最短路

    2种方式直接代码就可以了.注意首次不需要60S的转换 #include <map> #include <set> #include <list> #include ...

  9. UVa 10801 Lift Hopping (Dijkstra)

    题意:有一栋100层的大楼(标号为0~99),里面有n个电梯(不超过5个),以及要到达的层数(aid),然后是每个电梯走一层所需的时间, 再n行就是对应每个电梯可以到达的层数,数量不定.然后每装换一次 ...

随机推荐

  1. 《剑指offer》面试题64. 求1+2+…+n

    问题描述 求 1+2+...+n ,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C). 示例 1: 输入: n = 3 输出: 6 示 ...

  2. POSIX之消息队列

    my_semqueue_send.c: #include<stdio.h> #include<errno.h> #include<mqueue.h> #includ ...

  3. 巧用 Base62 解决字段太短的问题

    最近银联一纸 259 号改造通知,所有支付机构开始改造支付交易,上传终端信息. 不知道其他支付机构的小伙伴针对这次改造是否开始了? 由于这次银联给的时间非常少,我们这边改动涉及到相关上游一起改造,所以 ...

  4. gin中的SecureJSON 防止 json 劫持

    使用 SecureJSON 防止 json 劫持.如果给定的结构是数组值或map,则默认预置 "while(1)," 到响应体. package main import ( &qu ...

  5. 只要一行代码,实现五种 CSS 经典布局

    常用的页面布局,其实就那么几个.下面我会介绍5个经典布局,只要掌握了它们,就能应对绝大多数常规页面. 这几个布局都是自适应的,自动适配桌面设备和移动设备.代码实现很简单,核心代码只有一行,有很大的学习 ...

  6. 使用 MVVM Toolkit Source Generators

    关于 MVVM Toolkit 最近 .NET Community Toolkit 发布了 8.0.0 preview1,它包含了从 Windows Community Toolkit 迁移过来的以下 ...

  7. 学习Java第16天

    今天学习了HTML的表格,列表标签及表单. 顺序有点乱,明天学习swing awt,当时这部分大概过了一下,明天看视频 主要问题还是新概念较多,需要多理解,多记忆.

  8. 学习Java第6天

    今天所做的工作: 1.完成学生信息管理系统样卷 2.核心技术接口继承,多态 明天工作安排: 1.类的高级特性(Java类包) 2.异常处理 今天做一个小小的总结,Java程序是完全面向对象的,它的所有 ...

  9. C++ POD 类型

    POD 是 C++ 中一个比较重要的概念,POD 是英文 Plain Old Data 的缩写(通俗讲就是类或结构体通过二进制拷贝后还能保持其数据不变),用来描述一个类型(包括 class.union ...

  10. 女朋友让我深夜十二点催她睡觉,我有Python我就不干

    事情是这样的:今天晚上,女朋友让我十二点催她睡觉. 不过,可是我实在太困了,熬不下去-- 是吧?女朋友哪有睡觉重要? 但,女朋友的命令,我是不敢违抗的-- 但是睡觉也不能缺! 这时候我们该怎么办呢?是 ...