题意:
有一层不超过100层的大楼, 有n个电梯,它们的速度都不同。 而且每个电梯只能到达指定的那些楼层,而且它们都有各自的速度(即上升一层或下降一层所用的时间)。 如果一个人在某层走出电梯,要换一个电梯乘,那么他要等60秒(不管要等的是那个电梯,即使是刚刚出来的那个电梯也要等60秒)。在0层搭电梯出发时不需要等待。
一个人从0层开始,目的地是k层, 现在要搭这些电梯,问最少需多少时间。
思路:
建图,最短路
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
#include <algorithm>
#define fi first
#define se second
#define pii pair<int,int>
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long LL;
const int maxn = 100+5;
int n, k, done[maxn], dis[maxn], T[maxn], w[maxn][maxn];
vector<int> vec[maxn];
// 图
struct Edge{
int u, v;
Edge(int a = 0, int b = 0):u(a),v(b){}
};
vector<Edge> edges;
vector<int> G[maxn];
void init(int a){
for(int i = 0; i < a; ++i) G[i].clear();
edges.clear();
}
void addEdge(int u, int v){
edges.push_back(Edge(u,v));
edges.push_back(Edge(v,u));
int a = edges.size();
G[u].push_back(a-2);
G[v].push_back(a-1);
}
struct Node{
int d, u;
Node(int a = 0, int b = 0):u(a),d(b){}
bool operator < (const Node& rhs) const{
return d > rhs.d;
}
};
int Dijkstra(int s ,int t){
priority_queue<Node> Q;
memset(dis, 0x3f, sizeof(dis));
memset(done , 0, sizeof(done));
dis[s] = 0;
Q.push(Node(s,0));
while(!Q.empty()){
Node t = Q.top(); Q.pop();
int u = t.u;
if(done[u]) continue;
done[u] = 1;
for(int i = 0; i < G[u].size(); ++i){
Edge& e = edges[G[u][i]];
int v = e.v;
int extra = 0;
if(u != s) extra = 60;
if(dis[v] > dis[u] + w[u][v] + extra){
dis[v] = dis[u] + w[u][v] + extra;
Q.push(Node(v, dis[v]));
}
}
}
return dis[t];
}
int main()
{
freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&k) == 2&&n){
memset(w, 0x3f, sizeof(w));
for(int i = 0; i < n; ++i) vec[i].clear();
//init(n);
for(int i = 0; i < n; ++i) scanf("%d",&T[i]);
for(int i = 0; i < n; ++i){
char ch;
do{
int u; scanf("%d",&u);
vec[i].push_back(u);
}while((ch = getchar()) != '\n');
}
// 建图
for(int p = 0; p < n; ++p){
for(int i = 0; i < vec[p].size(); ++i){
for(int j = i+1; j < vec[p].size(); ++j){
int u = vec[p][i], v = vec[p][j];
int cost = abs(vec[p][i] - vec[p][j]) * T[p];
w[u][v] = w[v][u] = min(w[u][v], cost);
addEdge(vec[p][i], vec[p][j]);
}
}
}
int s = 0, t = k;
int ans = Dijkstra(s, t);
if(ans == INF) printf("IMPOSSIBLE\n");
else printf("%d\n",ans);
//printf("%d %d",vec[0].size(), vec[1].size());
}
return 0;
}