对于可以通过同一个电梯到达的楼层与楼层之间建边,边的权值为电梯的运动所需要花费的时间的值,然后从第0层开始使用迪杰斯特拉算法得出最终的结果,这里需要注意几个问题:边是双向的,也就是对应电梯既可以从下向上运动也可以从上向下运动,同时对于目标楼层为第0层的情况要进行特判,对于可达到的情况我们需要减去一个60,因为开始进入电梯的时候是不要转移的时间的,但是为了在代码中方便进行统一的处理,我们都加上了60。其他的具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
#include<functional>
using namespace std;
class Edge{
public:
int from,to,time,next;
Edge(int f = 0, int to = 0, int t = 0,int n=-1) :from(f), to(to), time(t),next(n){}
Edge operator=(const Edge& a){
from = a.from, to = a.to, time = a.time, next = a.next;
return *this;
}
};
Edge edge[50000];
class Solve{
public:
int n, k;
vector<int> t;
vector<int> floor[110];
int dist[110];
bool visit[110];
const int Inf = 0x3f3f3f3f;
int next[110];
int total;
void addEdge(int from,int to,int perTime){
edge[total] = Edge(from, to, abs(from - to)*perTime);
edge[total].next = next[from];
next[from] = total;
total++;
}
void Init(){
t.clear();
total = 0;
memset(next, -1, sizeof(next));
for (int i = 0; i < 110; i++){
floor[i].clear();
}
for (int i = 0; i < n; i++){
int temp;
cin >> temp;
t.push_back(temp);
}
for (int i = 0; i < n; i++){
while (true){
int temp1;
char temp2;
cin >> temp1;
temp2=getchar();
floor[i].push_back(temp1);
int amount = floor[i].size()-1;
for (int k1 = 0; k1 < amount; k1++){
addEdge(floor[i][k1], floor[i][amount], t[i]);
addEdge(floor[i][amount], floor[i][k1], t[i]);
}
if (temp2 == '\n') break;
}
}
}
void Deal(){
Init();
memset(dist, Inf, sizeof(dist));
memset(visit, 0, sizeof(visit));
dist[0] = 0;
for (int i = 0; i < 100; i++){
int ind=-1, Min = Inf;
for (int j = 0; j < 100; j++){
if (!visit[j] && dist[j] < Min){
Min = dist[j];
ind = j;
}
}
if (ind == -1) break;
visit[ind] = true;
for (int j = next[ind]; j != -1;j=edge[j].next){
int from = edge[j].from;
int to = edge[j].to;
if (dist[from]<Inf && dist[to] > dist[from] + edge[j].time + 60){
dist[to] = dist[from] + edge[j].time + 60;
}
}
}
if (k == 0) cout << "0\n";
else if (dist[k] == Inf) cout << "IMPOSSIBLE\n";
else cout << dist[k] - 60 << endl;
}
};
int main(){
Solve a;
while (cin >> a.n >> a.k){
a.Deal();
}
return 0;
}