UVA 10801 Lift Hopping (最短路)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1742

Problem ?

Lift Hopping

Time Limit: 1 second

Ted the bellhop: "I‘m coming up and if there isn‘t

a dead body by the time I get there, I‘ll make one

myself. You!"

Robert Rodriguez, "Four Rooms."

A skyscraper has no more than 100 floors, numbered from 0 to 99. It has n (1<=n<=5) elevators which travel up and down at (possibly) different speeds.
For each i in {1, 2,... n}, elevator number i takes Ti (1<=Ti<=100) seconds to travel between any two adjacent floors (going up or down). Elevators do not necessarily
stop at every floor. What‘s worse, not every floor is necessarily accessible by an elevator.

You are on floor 0 and would like to get to floor k as quickly as possible. Assume that you do not need to wait to board the first elevator you step into and (for simplicity)
the operation of switching an elevator on some floor always takes exactly a minute. Of course, both elevators have to stop at that floor. You are forbiden from using the staircase. No one else is in the elevator with you, so you don‘t have to stop if you don‘t
want to. Calculate the minimum number of seconds required to get from floor 0 to floor k (passing floor k while inside an elevator that does not stop there does not count as "getting to floor k").

Input

The input will consist of a number of test cases. Each test case will begin with two numbers, n and k, on a line. The next line will contain the numbers T1T2,... Tn.
Finally, the next n lines will contain sorted lists of integers - the first line will list the floors visited by elevator number 1, the next one will list the floors visited by elevator number 2, etc.

Output

For each test case, output one number on a line by itself - the minimum number of seconds required to get to floor k from floor 0. If it is impossible to do, print "IMPOSSIBLE" instead.

Sample Input Sample Output
2 30
10 5
0 1 3 5 7 9 11 13 15 20 99
4 13 15 19 20 25 30
2 30
10 1
0 5 10 12 14 20 25 30
2 4 6 8 10 12 14 22 25 28 29
3 50
10 50 100
0 10 30 40
0 20 30
0 20 50
1 1
2
0 2 4 6 8 10
275
285
3920
IMPOSSIBLE

Explanation of examples

In the first example, take elevator 1 to floor 13 (130 seconds), wait 60 seconds to switch to elevator 2 and ride it to floor 30 (85 seconds) for a total of 275 seconds.

In the second example, take elevator 1 to floor 10, switch to elevator 2 and ride it until floor 25. There, switch back to elevator 1 and get off at the 30‘th floor. The total time is

10*10 + 60 + 15*1 + 60 + 5*10 = 285 seconds.

In example 3, take elevator 1 to floor 30, then elevator 2 to floor 20 and then elevator 3 to floor 50.

In the last example, the one elevator does not stop at floor 1.


Problemsetter: Igor Naverniouk

Alternate solutions: Stefan Pochmann, Frank Pok Man Chu

题意:

有若干部电梯,给出每部电梯通过一层的时间和能停的楼层,换乘电梯要用60s,电梯可上可下,求从0层到目标层的最短时间。

分析:

最短路。假设目前在i电梯j层,那么能更新的状态有两种:i电梯的其他楼层和j楼层的其他电梯。这也是建图的依据,感觉这题不显式地建图会方便些。

/*
 *
 *	Author	:	fcbruce
 *
 *	Date	:	2014-09-03 16:31:53
 *
 */
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <cctype>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>
#define sqr(x) ((x)*(x))
#define LL long long
#define itn int
#define INF 0x3f3f3f3f
#define PI 3.1415926535897932384626
#define eps 1e-10

#ifdef _WIN32
	#define lld "%I64d"
#else
	#define lld "%lld"
#endif

#define maxm
#define maxn 101

using namespace std;

int n,obj;

int v[5];
vector <int> stop[5];
int G[5][maxn],d[5][maxn];
pair<int,int> q[maxn<<8];
bool inq[5][maxn];

void SPFA()
{
	memset(d,0x3f,sizeof d);
	memset(inq,0,sizeof inq);
	int f=0,r=-1;
	for (int i=0;i<n;i++)
		if (G[i][0])
		{
			q[++r]=make_pair(i,0);
			d[i][0]=0;
		}

	while (f<=r)
	{
		pair<int,int> x=q[f++];
		inq[x.first][x.second]=false;
		for (int u:stop[x.first])
		{
			if (d[x.first][u]>d[x.first][x.second]+abs(x.second-u)*v[x.first])
			{
				d[x.first][u]=d[x.first][x.second]+abs(x.second-u)*v[x.first];
				if (!inq[x.first][u])
				{
					inq[x.first][u]=true;
					q[++r]=make_pair(x.first,u);
				}
			}
		}
		for (int i=0;i<n;i++)
		{
			if (x.first==i || G[i][x.second]==false)	continue;
			if (d[i][x.second]>d[x.first][x.second]+60)
			{
				d[i][x.second]=d[x.first][x.second]+60;
				if (!inq[i][x.second])
				{
					inq[i][x.second]=true;
					q[++r]=make_pair(i,x.second);
				}
			}
		}
	}
}

int main()
{
	#ifdef FCBRUCE
		freopen("/home/fcbruce/code/t","r",stdin);
	#endif // FCBRUCE

	char str[233];

	while (~scanf( "%d%d",&n,&obj))
	{
		memset(G,0,sizeof G);

		for (int i=0;i<n;i++)
			scanf( "%d",v+i);

		getchar();

		for (int i=0;i<n;i++)
		{
			gets(str);
			stringstream s(str);
			int x;
			stop[i].clear();
			while (s>>x)
			{
				stop[i].push_back(x);
				G[i][x]=true;
			}
		}

		SPFA();

		int MIN=INF;

		for (int i=0;i<n;i++)
			if (G[i][obj])	MIN=min(MIN,d[i][obj]);

		if (MIN==INF)
			puts( "IMPOSSIBLE");
		else
			printf( "%d\n",MIN);
	}

	return 0;
}
时间: 2024-08-05 14:57:47

UVA 10801 Lift Hopping (最短路)的相关文章

uva 10801 - Lift Hopping(最短路Dijkstra)

1 /* 2 题目大意: 3 就是一幢大厦中有0-99的楼层, 然后有1-5个电梯!每个电梯有一定的上升或下降速度和楼层的停止的位置! 4 问从第0层楼到第k层最少经过多长时间到达! 5 6 思路:明显的Dijkstra ,在建图的时候u->v可能有多个电梯到达,取时间最少的当作路径的权值! 7 如果我们发现 d[i] > d[j] + map[j][i] + 60, 那么说明从第0层到达第 i 层的时间大于从第j层 8 转移到其他电梯然后到达第 i 层的时间,那么就更新d[i]的值! 9 1

UVA 10801 Lift Hopping 最短路

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

[UVA 10801]Lift Hopping[Dijkstra][建图]

题目链接:[UVA 10801]Lift Hopping[Dijkstra][建图] 题意分析: 从0层开始,一共有n台电梯供你到达目的地k层.每台电梯往上走一层都要消耗t[i]的时间,并且电梯只能在特定的楼层停下,换乘电梯要花费60s的时间,而且呢,你不能用楼梯上楼,只能搭电梯....(hentai!)问:最快到达楼层k的时间是多少?不能到达就输出-1. 解题思路: 这题技巧就是体现在建图上,图建好了,用dijkstra跑一遍就行了. 具体建图就是用mp[i][j]代表从楼层i到楼层j的最小距

UVA 10801 Lift Hopping Floyd

题目链接:UVA - 10801 题意描述:有n个电梯,给出每个电梯可以到达的楼层位置和电梯上升或下降一层楼的时间,另外在同一层楼换乘不同的电梯需要等待一分钟,问从楼层位置0(即地面)到第k层楼需要的最短时间是多少. 算法分析:由于n很小(n<100),所有可以用Floyd算法搞之.注意换乘电梯时需要加上那60秒即可了. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include&l

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

题意:有n<6部电梯,给出每部电梯可以停的一些特定的楼层,要求从0层到达第k层出来,每次换乘需要60秒,每部电梯经过每层所耗时不同,具体按 层数*电梯速度 来算.问经过多少秒到达k层(k可以为0)? 思路:dijkstra再加一些特殊的处理就行了.首先要考虑,如何建图: (1)每层作为一个点.但是特定路径可以有多种权,比如从2->5可以坐1号电梯10s,但是坐2号只需要5s,所以有重边. (2)k=0时,不耗时间. (3)有多种路径可达同一楼层且权值相同,那么从本楼层到另一楼层有多种选择,有时

UVa 10801 - Lift Hopping

根据题意,以每一层楼为顶点,每个电梯可以到达的两层楼之间的秒数为每一条边的权值,以此构建一个无向图.然后利用dijkstra求出最短的时间,注意每次换乘电梯需要等待60s(因为同一个电梯上的楼层是相互可达的,所以我们只有通过另外一个电梯找到了更小的搭乘时间时候我们才会执行松弛操作),因此每转一个定点需要加60s时间(注意初始定点不需要60s的等待). #include <bits/stdc++.h> using namespace std; const int INF=0x3f3f3f3f;

UVa 10801 Lift Hopping【floyd 】

题意:给出n个电梯,每个电梯的运行时间,每个电梯只能在相应的楼层停靠,而且没有楼梯,再给出想去的楼层,问从0层能否到达想去的楼层,求到达的最短时间 建图还是没有建出来--- 因为n<100,可以用floyd 考虑到d[i][j]=min(d[i][j],d[i][k]+d[k][j]) d[i][k]+d[k][j],表示从第i层到达了第k层,又从第k层到达了第j层,说明在  k 层的时候换乘了电梯,需要加一个60 然后就是输入过程中,一直维护d[i][j]的最小值,更新的时候往上往下都要更新(

[题解]UVA10801 Lift Hopping

链接:http://vjudge.net/problem/viewProblem.action?id=22172 描述:有n部电梯,每部电梯都有不能停下的楼层,要求搭乘电梯从第0层到第k层. 思路:单源点最短路 建图:将每层楼拆成n个点,用边权解决换乘等待的时间.将每部电梯能到达的楼层顺次连接,边权是该电梯经过所需时间.最后建立一个超级源点S,连接每部电梯的第0层的节点,边权为0,方便统计答案. 下面是我的实现,Dijkstra版本: 1 #include <iostream> 2 #incl

uva 11248 Frequency Hopping (最大流)

uva 11248 Frequency Hopping 题目大意:给定一个有向网络,每条边均有一个容量. 问是否存在一个从点1到点N.流量为C的流.假设不存在,能否够恰好改动一条弧的容量,使得存在这种流. 解题思路:先依照题目给出的边建好图,然后跑一发最大流,得到原始最大流C1,假设C1==C或者C==0时.能够直接输出possible.假设不存在这种流.那么開始找割边,将这些割边的容量添加C,再求最大流.假设能够,那么要输出全部的方案.改动全部割边后,仍没有符合条件的流,输出 not poss