UVA - 10801 Lift Hopping (Dijkstra)

题意:
有一栋楼100层,从0到99编号层数,有多部电梯(最多5部),给出每部每部电梯的速度,即上或下一层楼所用的秒数。
然后每部电梯不一定在所有楼层出现,给你所有电梯可能出现的层数。给你一个目标层,要你从0层开始到目标层,问所用时间最短。在0层的时候选择做哪步电梯出发不需要时间的,但是在中间的楼层,想换电梯的时候,需要60秒。

解析:Dijkstra算法,用邻接矩阵建图。先把每个电梯能到达的层的所有起点与终点,所用的时间存到邻接矩阵中。如果某条路经已有,那么注意要保存所需时间最少的那个。

注意:终点楼层可能就是0层,所以要特殊判断,输出0。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 105;
int floor[N],d[N],t[N];
int w[N][N];
int vis[N];
int n,k;
void init() {
	memset(w,INF,sizeof(w));
	for(int i = 0; i < N; i++) {
		w[i][i] = 0;
	}
}
void dijkstra(int s) {
	for(int i = 0; i < N; i++) {
		d[i] = INF;
	}
	d[s] = 0;
	memset(vis,0,sizeof(vis));
	for(int i = 0; i < N; i++) {
		int x, m = INF;
		for(int y = 0; y < N; y++) {
			if(!vis[y] && d[y] <= m) {
				x = y;
				m = d[y];
			}
		}
		vis[x] = true;
		for(int y = 0; y < N; y++) {
			d[y] = min(d[y], d[x] + w[x][y] + 60);
		}
	}
}
void read_line(int cur) {
	char ch;

	int pos = 0;
	do{
		scanf("%d",&floor[pos++]);
	}while( (ch = getchar()) != '\n');
	for(int i = 0; i < pos; i++) {
		for(int j = i+1; j < pos; j++) {
			int dis = abs(floor[i] - floor[j]) * t[cur];
			w[floor[i]][floor[j]] = w[floor[j]][floor[i]] = min(w[floor[j]][floor[i]],dis);
		}
	}
}
int main() {
	while(scanf("%d%d",&n,&k) != EOF) {
		for(int i = 1; i <= n; i++) {
			scanf("%d",&t[i]);
		}
		init();
		for(int i = 1; i <= n; i++) {
			read_line(i);
		}
		dijkstra(0);
		if(d[k] == INF) {
			printf("IMPOSSIBLE\n");
		}else {
			if(k == 0) {
				printf("0\n");
			}else {
				printf("%d\n",d[k]-60);
			}
		}
	}
	return 0;
}

你可能感兴趣的:(HDU,lift,Hopping,10801)