题目大意:有n个电梯,每个电梯有制定停靠的楼层,如果你从一个电梯换乘另一个电梯需要等待60s。一开始你在0层,在0层的时候不需要等待。现在指定你要到的楼层,问你通过这n个电梯到达目标楼层的最快时间。
解题思路:这题是最短路算法,但是不容易转化,因为你需要先处理出可以停靠的任意两个楼层之间的最短时间,然后再转换成你从0层到目标层的最短路问题,之后的每次松弛需要加上等待时间,因为换乘电梯了。注意:0层的时候要特判,因为是不需要等待的。
代码:
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
typedef pair<int, int>pii;
priority_queue<pii, vector<pii>, greater<pii> >q;
const int maxn = 10;
const int maxm = 100;
const int INF = 1e6;
const int wait = 60;
int t[maxn];
int floor[maxm];
int w[maxm][maxm];
int d[maxm];
void read_Graph (int n, int k) {
int pos;
char ch;
for (int i = 0; i < maxm; i++)
for (int j = i; j < maxm; j++)
w[j][i] = w[i][j] = (i==j)? 0 : INF;
for (int i = 0; i < n; i++)
scanf ("%d", &t[i]);
for (int i = 0; i < n; i++) {
pos = 0;
do {
scanf ("%d%c", &floor[pos++], &ch);
} while (ch != ‘\n‘);
for (int j = 0; j < pos; j++)
for (int x = j; x < pos; x++)
if (w[floor[x]][floor[j]] > (floor[x] - floor[j]) * t[i])
w[floor[x]][floor[j]] = w[floor[j]][floor[x]] = (floor[x] - floor[j]) * t[i];
}
}
int Dijkstra (int n, int k) {
for (int i = 0; i < maxm; i++)
d[i] = INF;
d[0] = 0;
pii u = make_pair(d[0], 0);
q.push(u);
while (!q.empty()) {
u = q.top();
q.pop();
if (u.first != d[u.second]) continue;
for (int i = 0; i < maxm; i++) {
if (i == u.second) continue;
if (u.second == 0) {
if (d[i] > u.first + w[u.second][i])
d[i] = u.first + w[u.second][i];
q.push(make_pair(d[i], i));
} else if (d[i] > u.first + w[u.second][i] + wait) {
d[i] = u.first + w[u.second][i] + wait;
q.push(make_pair(d[i], i));
}
}
}
return d[k];
}
int main () {
int n, k;
while (scanf ("%d%d", &n, &k) != EOF) {
read_Graph(n, k);
int ans = Dijkstra(n, k);
if (ans == INF)
printf ("IMPOSSIBLE\n");
else
printf ("%d\n", ans);
}
return 0;
}
时间: 2024-11-04 11:57:31