把每个电梯口看作一个节点, 然后计算边的权值的时候处理一下, 就ok了。
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;
const int MAXN = 112;
struct Edge { int v, id; };
struct node
{
int t, v, id;
bool operator < (const node& rhs) const
{
return t > rhs.t;
}
};
vector<Edge> g[MAXN];
vector<int> a;
int d[MAXN], speed[10], n, k, x;
void solve()
{
priority_queue<node> q;
REP(i, 0, MAXN) d[i] = (i == 0 ? 0 : 1e9);
q.push(node{0, 0, -1});
while(!q.empty())
{
node x = q.top(); q.pop();
int u = x.v;
if(x.t != d[u]) continue;
REP(i, 0, g[u].size())
{
int v = g[u][i].v, id = g[u][i].id;
int w = speed[id] * abs(u - v);
if(x.id != id && x.id != -1) w += 60;
if(d[v] > d[u] + w)
{
d[v] = d[u] + w;
q.push(node{d[v], v, id});
}
}
}
if(d[k] == 1e9) puts("IMPOSSIBLE");
else printf("%d\n", d[k]);
}
int main()
{
while(~scanf("%d%d", &n, &k))
{
REP(i, 0, MAXN) g[i].clear();
REP(i, 0, n) scanf("%d", &speed[i]);
REP(i, 0, n)
{
a.clear();
scanf("%d", &x);
a.push_back(x);
while(getchar() != '\n')
{
scanf("%d", &x);
a.push_back(x);
}
REP(r, 0, a.size())
REP(j, r + 1, a.size())
{
g[a[j]].push_back(Edge{a[r], i});
g[a[r]].push_back(Edge{a[j], i});
}
}
solve();
}
return 0;
}