最短路问题,不过起点不只是1个,终点也不止1个,因此把不同电梯的楼层分别编号,相邻楼层之间连边,不同电梯的相同楼层之间连边。
dij的时候一次性把所有起点压到队列中,如果直接套版可以加一超级源点s和所有起点连一条dist为0的边。
需要维护的信息:
为了判断之前电梯有没有出现相同楼层,需要维护一个楼层到点编号的映射,为了判断终点,需要维护点编号到楼层的映射。
#include<bits/stdc++.h> using namespace std; int n,k; const int maxn = 100; typedef long long ll; vector<int> lift[5]; int id[5][maxn]; //判断出现 和 换乘 int flrId[5*maxn]; //结点对应的楼层,判断终点用 int sp[5];//speed #define PB push_back struct Edge { int v,w; }; int vcnt; //结点编号从1开始 vector<Edge> edges; vector<int> G[maxn*5+1]; void addEdge(int u,int v,int w) { G[u].PB(edges.size()); edges.PB({v,w}); } void AddEdge(int u,int v,int w) { addEdge(u,v,w); addEdge(v,u,w); } const ll INF = 0x3f3f3f3f3f3f3f3fLL; ll d[maxn]; typedef pair<int,int> Node; #define fi first #define se second ll dijkstra(int tflr = k) { fill(d+1,d+1+vcnt,INF); priority_queue<Node,vector<Node>,greater<Node> > q; for(int i = 0; i < n; i++) if(id[i][0]){ q.push(Node(0,id[i][0])); d[id[i][0]] = 0; } while(q.size()){ Node x = q.top(); q.pop(); int u = x.se; if(flrId[u] == tflr) return d[u]; if(d[u] != x.fi) continue; for(int i = 0; i < G[u].size(); i++){ Edge &e = edges[G[u][i]]; if(d[e.v] > d[u] + e.w){ d[e.v] = d[u] + e.w; q.push(Node(d[e.v],e.v)); } } } return INF; } bool sscan_l(int &x,char *&s)//非负数 { while(!isdigit(*s)){ if(!*s) return false; s++; } x = *s-'0'; while(s++,isdigit(*s)) x = x*10+*s-'0'; return true; } char str[233]; void read() { for(int i = 0; i < n; i++) scanf("%d",sp+i); scanf(" "); for(int i = 0; i < n; i++) { gets(str); char *p = str; int floor; lift[i].clear(); while(sscan_l(floor,p)){ lift[i].PB(floor); } } } void buildGraph() { for(int i = 0; i < n; i++){ int sz = lift[i].size(); if(sz){ int flr = lift[i][0]; id[i][flr] = ++vcnt; flrId[vcnt] = flr; G[vcnt].clear(); for(int k = 0; k < i; k++) if(id[k][flr]){ AddEdge(vcnt,id[k][flr],60); } for(int j = 1; j < sz; j++){ flr = lift[i][j]; id[i][flr] = ++vcnt; flrId[vcnt] = flr; G[vcnt].clear(); for(int k = 0; k < i; k++) if(id[k][flr]){ AddEdge(vcnt,id[k][flr],60); } int cost = (flr-lift[i][j-1])*sp[i]; AddEdge(vcnt-1,vcnt,cost); } } } } void init() { memset(id,0,sizeof(id)); vcnt = 0; edges.clear(); } int main() { //freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&k)){ init(); read(); buildGraph(); ll ans = dijkstra(); if(ans<INF){ printf("%lld ",ans); }else puts("IMPOSSIBLE"); } return 0; }